2012-09-07 2 views
3

현재 클래스 나 그 조상에 존재하지 않는 속성에 액세스하려는 시도가 구성원의 속성에 액세스하려고 시도하는 클래스를 구현하려고합니다. 아래는 내가하려고하는 사소한 버전입니다.왜 "마술처럼"불려지는 메소드에 대해 __getattr__이 호출되지 않습니까?

class Foo: 
    def __init__(self, value): 
     self._value = value 

    def __getattr__(self, name): 
     return getattr(self._value, name) 

if __name__ == '__main__': 
    print(Foo(5) > Foo(4)) # should do 5 > 4 (or (5).__gt__(4)) 

그러나 이것은 TypeError을 발생시킵니다. 심지어 operator 모듈의 attrgetter 클래스를 사용해도 똑같은 일을합니다. the documentation regarding customizing attribute access을 살펴 보았지만 쉽게 읽을 수는 없었습니다. 이 문제를 어떻게 해결할 수 있습니까?

+1

좋은 간단한 예를 들어 주셔서 감사합니다.하지만 '바'의 요점은 무엇입니까? 당신의 질문은 그것없이 다르지 않습니다. –

+0

@ ron.rothman, * shrugs shoulders * 내 코드가하는 기본적인 요지입니다. 나는 그것을 더 단순화했다. :) –

+0

또한 속성은 int가 아닌 문자열입니다. 'Foo (5)'를 사용하면 아마도 둘을 하나로 묶어 놓았을 것입니다. –

답변

7

, 무슨 일을하는 것은 정확하지만 여전히 당신이 그것을 사용하려고하는지에 대해 작동하지 않습니다 : LocalProxy를 사용할 때 코드는 다음과 같을 것이다. 그 이유는 암시적인 마법 검색은 __getattr__ (또는 __getattribute__ 또는 다른 어떤 것)을 사용하지 않기 때문입니다. 메서드는 실제로 마법의 이름과 함께 명시 적으로 있어야합니다. 귀하의 접근 방식은 일반적인 속성에 대해서는 작동하지만 마법 방법에 대해서는 작동하지 않습니다. (명시 적 Foo(5).__lt__(4)을 할 경우, 그것은 작동합니다, 그것은 예를 들어, < 사용 __lt__ 호출 --- 단지 암시 "마법"조회의) ---이 차단됩니다)

This post가 접근 방법을 설명합니다. 메타 클래스를 사용하여 마법 방법을 자동 생성합니다. 특정 메소드 만 필요하면 클래스에서 수동으로 정의 할 수 있습니다.

+0

흥미 롭습니다. 그러나 수동으로 이러한 메서드를 만드는 것이 더 읽기 쉽지 않은지 궁금합니다. – ThiefMaster

+0

흠. 이 모든 것을 구현하는 커스텀 클래스에서 서브 클래 싱을하는 대신 데코레이터를 사용하는 것이 더 나을 것입니다. 그냥 내 모든 옵션을보고. –

+0

@mgilson,'Foo'가''__gt__'과'__lt__'을 구현한다면 안됩니다? –

1

__*__ 실제로 존재하지 않으면 메소드가 작동하지 않으므로 __getattr____getattribute__도 이러한 호출을 프록시 할 수 없습니다. 모든 단일 메소드를 수동으로 작성해야합니다.

예, 여기에는 복사본 & 붙여 넣기가 포함되어 있습니다. 그리고 네,이 경우에는 완벽합니다.

werkzeug LocalProxy 클래스를 기본 클래스로 사용하거나 자신의 클래스 대신 사용할 수 있습니다. 내가 제대로 이해하면

print(LocalProxy(lambda: 5) > LocalProxy(lambda: 4)) 
관련 문제