2010-05-17 4 views
1

필자는 전통적으로 Perl 및 C++ 프로그래머입니다. 파이썬에 대해 사소한 것을 오해하고 있다면 사전에 사과드립니다!Python : 참조에 대한 참조를 만드는 방법은 무엇입니까?

참조에 대한 참조를 만들고 싶습니다. 응? 승인. 파이썬의 모든 객체는 실제 객체에 대한 참조입니다. 그럼이 참조에 대한 참조를 어떻게 만듭니 까?

왜 내가 필요합니까/필요합니까? sys.stdout 및 sys.stderr을 오버라이드하여 로깅 라이브러리를 작성합니다. 나는 sys.stdout에 대한 (2 차 수준의) 참조를 원한다.

참조에 대한 참조를 만들 수 있다면 init 함수가 재정의 될 파일 핸들 참조 (예 : sys.stdout 또는 sys.stderr)에 대한 참조를받는 일반 로거 클래스를 만들 수 있습니다. . 현재 두 값을 모두 하드 코딩해야합니다.

건배, 케빈

답변

0

이는 할 수 없습니다. 원하는 속성을 문자열로 전달하고 getattr()setattr()을 사용하십시오.

1

파이썬에서 참조에 대한 참조를 만들 수 없습니다. 말했다

import sys 

class MyLogger: 
    def __init__(self, f): 
     self.f = f 

    def __getattr__(self, name): 
     # forward e.g. flush() calls to the original file 
     return getattr(self.f, name) 

    def write(self, data): 
     # log the data here! 
     # ... 

     # And write to the original file 
     self.f.write(data) 

sys.stdout = MyLogger(sys.stdout) 
sys.stderr = MyLogger(sys.stderr) 
+0

얼굴이 그 [sys.stdout = MyLogger (SYS는 .stdout)]는 파이썬이 무언가를 놓치고 있다는 증거가 될 수 없다. 아직도 나는 내가 본 모든 것을 좋아한다. 다행히도 두 가지 파일 핸들 만 재정의 할 수 있습니다. 나는 두 번 반복 할 수있는 '여유'=) 조언을 주셔서 감사합니다. 이 솔루션은 필자의 원래 요구 사항에 가장 밀접하게 부합합니다. – kevinarpe

+0

아, 또한. \ __ getattr__이있는 멋진 팁. 나는 추가 할 것이다. – kevinarpe

+0

'stdout'과'stderr'를 오버라이드 했습니다만,'write' 메소드를 가진 객체/클래스로 대체 할 수 있습니다 (대체 파일처럼'sys.stdout = open ('mylog ','wb ')'이 효과적 일 것입니다.) 제한이 없다고 생각합니다. 다른 철학과는 다른 언어 일뿐입니다. 파이썬 철학에 반대하는 객체에 대한 참조입니다 (http : // www. python.org/dev/peps/pep-0020/), 필자는 perl의 "표현형"모델에 맞을 것이라고 확신하지만 자신의 장점과 단점을 가지고 있습니다 : -P – cryo

6

쉽게 완료보다 : 당신은 그러나 자신의 로깅 시스템을 허용 write 등의 방법으로 사용자 정의 클래스와 stderrstdout 파일을 덮어 쓸 수 있습니다

ostream = sys.stdout 
print >> ostream, 'hi mom!' 
ostream = sys.stderr 
print >> ostream, 'hi mom!' 
ostream = open('mylog.txt', 'a') 
... 

를 표준 logging module 볼 때 당신을 당신의 벨트 밑에 파이썬이 좀 더 있습니다.

이 답변은 질문의 수준에서 실제로 필요한 것이 무엇인지 추정 한 것입니다. 참조에 대한 참조의 개념은 Python으로 필요하지 않습니다, 당신은 목록을 다중화하거나 원하는 경우 DICT :

outputs = [sys.stderr, my_open_file_object_which_is_really_a_reference] 
print >> outputs[0], 'hi dad!' 
outputs = {'terminal': sys.stderr, 'logfile': file_object} 
print >> outputs['logfile'], 'goodbye world!' 

등등.

+0

+1 표준 로깅 모듈을 언급합니다. –

0

먼저, 이미 logging 모듈이 있으므로 아마도 이것을 사용해야 할 것입니다. 둘째, 참조에 대한 참조와 같은 것이 없지만 래퍼 또는 함수를 통해 간접 참조를 달성 할 수 있습니다. 당신이 있다면 예를 들어, 같은 객체를 할당하기위한 getter 및 setter 함수를 만드는 방법 :

class StdOutWrapper(object): 
     def __init__(self): 
      self.original = sys.stdout 

     @property 
     def value(self): 
      return sys.stdout 

     @value.setter 
     def value(self,val): 
      sys.stdout = val 

그런 다음/역 참조 sys.stdout을 할당 로거에이 개체의 인스턴스를 전달할 수 있습니다. 다른 답변이 말하는 것처럼

+0

이 솔루션의 문제점은 sys.stdout을 하드 코딩해야한다는 것입니다. 이 클래스는 일반적으로 생성 할 수 없습니다. – kevinarpe

+0

@KCArpe, 예, 맞습니다. 래퍼를 사용하도록 만든 코드를 저장하려고했습니다 ... 래퍼 자체는 sys.stdout과 sys.stdin 모두에 대해 작성해야합니다. –

0

는 파이썬에서 진정한 "참조 참조"이 없지만, 거의 같은 효과를 가져 오는 방법이 있습니다 :

>>> reference1 = "Some Data" 
>>> reference2 = (reference1,) 
>>> def f(data): 
    print data 

>>> f(reference2) 
('Some Data',) 
>>> f(*reference2) 
Some Data 
관련 문제