2013-07-11 4 views
3

프록시 클래스를 생성하기 위해 this 레시피를 찾았습니다. 사용자 지정 개체를 래핑하는 데 사용했으며 특정 속성에 과부하를 걸고 새로운 특성을 프록시에 첨부하려고합니다. 그러나 (프록시 클래스 내에서) 프록시에 대한 모든 메서드를 호출 할 때, 결국 원하는 wrappee 위임되는 끝납니다.파이썬 객체 프록시 : 프록시에 액세스하는 방법

프록시에 대한 참조를 액세스하거나 저장하는 방법이 있습니까?

다음은 문제를 설명하기위한 몇 가지 코드 (테스트되지 않음)입니다. 내 문제는 프록시가 모두 자신의 방법/속성을 숨기고 (가해야 할 일이다) 프록시 개체로 자체 포즈도 잘 작동하는 의미에서

class MyObject(object): 
    @property 
    def value(self): 
    return 42 

class MyObjectProxy(Proxy): # see the link above 
    def __getattribute__(self, attr): 
    # the problem is that `self` refers to the proxied 
    # object and thus this throws an AttributeError. How 
    # can I reference MyObjectProxy.another_value()? 
    if attr == 'value': return self.another_value() # return method or attribute, doesn't matter (same effect) 
    return super(MyObjectProxy, self).__getattribute__(attr) 

    def another_value(self): 
    return 21 

o = MyObject() 
p = MyObjectProxy(o) 
print o.value 
print p.value 

...

아래의 의견을 바탕으로

, 나는이에 __getattribute__을 변경 업데이트 :

def __getattribute__(self, attr): 
    try: 
     return object.__getattribute__(self, attr) 
    except AttributeError: 
     return super(MyObjectProxy, self).__getattribute__(attr) 

이 참조 ms 지금 트릭을 할 수 있지만이 직접적으로 Proxy 클래스에 추가하는 것이 좋습니다.

답변

0

코드가 잘못 된 이유는 루프__getattribute__입니다. __getattribute__을 재정의하여 프록시 클래스 자체의 특정 속성에 접근 할 수 있습니다. 그러나 보자.

p.value으로 전화하면 __getattribute__이 호출됩니다. 그런 다음 여기에 if attr == 'value': return self.another_value()이옵니다. 여기서 another_value으로 전화하여 __getattribute__을 다시 입력해야합니다.

이번에는 여기에 return super(MyObjectProxy, self).__getattribute__(attr)이옵니다. Proxy__getattribute__이라고하고 another_valueMyobject에 가져 오려고 시도합니다. 따라서 예외가 발생합니다.

우리는 마침내 가야 할 return super(MyObjectProxy, self).__getattribute__(attr)으로가는 추적 표시에서 볼 수 있습니다.

Traceback (most recent call last): 
    File "proxytest.py", line 22, in <module> 
    print p.value 
    File "proxytest.py", line 13, in __getattribute__ 
    if attr == 'value': return self.another_value() # return method or attribute, doesn't matter (same effect) 
    File "proxytest.py", line 14, in __getattribute__ 
    return super(MyObjectProxy, self).__getattribute__(attr) 
    File "/home/hugh/m/tspace/proxy.py", line 10, in __getattribute__ 
    return getattr(object.__getattribute__(self, "_obj"), name) 
AttributeError: 'MyObject' object has no attribute 'another_value' 

편집 :
변경 if attr == 'value': return object.__getattribute__(self, 'another_value')()에 코드 if attr == 'value': return self.another_value()의 라인.

+0

@zhangyangyu를 재생산하고 확인해 주셔서 감사합니다. 원하는 동작을 얻는 방법에 대한 제안? – orange

+0

답변을 업데이트했습니다. 확인하시기 바랍니다. @orange – zhangyangyu

+0

나는 그 일을 전에 시도 했었다고 생각했지만 실수했을 것입니다. 당신의 솔루션은 잘 작동합니다. 프록시 된 클래스에 접근하기 전에 먼저 자체 속성을 찾기 위해'proxy' 클래스를 고쳐 보겠습니다. – orange