__getattribute__
속성 액세스가 발생할 때마다 호출됩니다.
class Foo(object):
def __init__(self, a):
self.a = 1
def __getattribute__(self, attr):
try:
return self.__dict__[attr]
except KeyError:
return 'default'
f = Foo(1)
f.a
이로 인해 무한 재귀가 발생합니다. 여기서 범인은 선 return self.__dict__[attr]
입니다. 모든 속성이 self.__dict__
이름으로 저장 되고 사용 가능한 것으로 가장합니다 (진실에 가깝습니다) . 라인
f.a
의 a
속성에 액세스하려고합니다 f
. 이 호출합니다 f.__getattribute__('a')
. __getattribute__
그런 다음로드를 시도합니다 self.__dict__
. __dict__
의 속성 self == f
이므로 파이썬 호출 은 속성에 f.__getattribute__('__dict__')
다시 액세스하려고합니다 '__dict__
. 이것은 무한 재귀입니다.
__getattr__
대신에 사용 되었다면
- 때문에 실행이없는 것이 결코
f
있다a
속성 입니다.
- 실행했다면 (당신이 요청했다고 가정 해보십시오
f.b
) __dict__
이미 거기에 있기 때문에 찾기 위해 호출되지 않았 으며 속성을 찾는 다른 모든 방법이 실패한__getattr__
경우에만 호출됩니다 .
위의 클래스를 사용하여 '올바른'방법 __getattribute__
은
class Foo(object):
# Same __init__
def __getattribute__(self, attr):
return super(Foo, self).__getattribute__(attr)
super(Foo, self).__getattribute__(attr)
__getattribute__
'가장 가까운'수퍼 클래스의 메소드 (공식적으로 클래스의 메소드 분석 순서 (MRO)의 다음 클래스)를 현재 오브젝트에 바인딩 합니다.self
후 호출하여 작업을 수행 할 수 있도록합니다.
이 문제는 __getattr__
파이썬 이 속성을 찾을 수 없을 때까지 정상적인 일 을 할 수있게 함으로써 피할 수 있습니다 . 그 시점에서 파이썬 손은 __getattr__
메소드 를 제어 하고 무언가를 생각해냅니다.
또한을 사용하여 무한 재귀에 빠질 수 있다는 점도 주목할 가치가 있습니다 __getattr__
.
class Foo(object):
def __getattr__(self, attr):
return self.attr
나는 그것을 운동으로 남겨 두겠습니다.