__getattr__
멋진 것을하기 위해 클래스 의 메소드 를 재정의하고 싶지만 기본 동작을 중단하고 싶지 않습니다.
이 작업을 수행하는 올바른 방법은 무엇입니까?
답변
재정의 __getattr__
는 좋을 __getattr__
것입니다. 인스턴스에 이름과 일치하는 속성이없는 경우에만 최후의 수단으로 호출됩니다. 당신이 액세스하는 경우 예를 들어 foo.bar
, 다음 __getattr__
경우에만 호출 될 것이다 foo
라는 어떤 속성이 없습니다 bar
. 처리하지 않으려는 속성 인 경우 다음을 발생시킵니다 AttributeError
.
class Foo(object):
def __getattr__(self, name):
if some_predicate(name):
# ...
else:
# Default behaviour
raise AttributeError
그러나, 달리 __getattr__
, __getattribute__
(해당 상속 객체들을, 즉 새로운 스타일의 클래스에 대한 작업)를 먼저 호출됩니다. 이 경우 다음과 같이 기본 동작을 유지할 수 있습니다.
class Foo(object):
def __getattribute__(self, name):
if some_predicate(name):
# ...
else:
# Default behaviour
return object.__getattribute__(self, name)
자세한 내용 은 Python 문서를 참조하십시오 .
답변
class A(object):
def __init__(self):
self.a = 42
def __getattr__(self, attr):
if attr in ["b", "c"]:
return 42
raise AttributeError("%r object has no attribute %r" %
(self.__class__.__name__, attr))
>>> a = A()
>>> a.a
42
>>> a.b
42
>>> a.missing
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 8, in __getattr__
AttributeError: 'A' object has no attribute 'missing'
>>> hasattr(a, "b")
True
>>> hasattr(a, "missing")
False
답변
Michael 답변을 확장하려면을 사용하여 기본 동작을 유지하려면 __getattr__
다음과 같이하십시오.
class Foo(object):
def __getattr__(self, name):
if name == 'something':
return 42
# Default behaviour
return self.__getattribute__(name)
이제 예외 메시지가 더 설명 적입니다.
>>> foo.something
42
>>> foo.error
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 5, in __getattr__
AttributeError: 'Foo' object has no attribute 'error'