방법은 어떻게 __getattribute__
사용됩니까?
일반적인 점선 조회 전에 호출됩니다. 상승 AttributeError
하면을 호출 __getattr__
합니다.
이 방법의 사용은 다소 드뭅니다. 표준 라이브러리에는 두 가지 정의 만 있습니다.
$ grep -Erl "def __getattribute__\(self" cpython/Lib | grep -v "/test/"
cpython/Lib/_threading_local.py
cpython/Lib/importlib/util.py
모범 사례
단일 속성에 대한 액세스를 프로그래밍 방식으로 제어하는 적절한 방법은 property
. 클래스 D
는 다음과 같이 작성되어야합니다 (선택적으로 의도 된 동작을 복제하기 위해 setter 및 deleter 사용).
class D(object):
def __init__(self):
self.test2=21
@property
def test(self):
return 0.
@test.setter
def test(self, value):
'''dummy function to avoid AttributeError on setting property'''
@test.deleter
def test(self):
'''dummy function to avoid AttributeError on deleting property'''
그리고 사용법 :
>>> o = D()
>>> o.test
0.0
>>> o.test = 'foo'
>>> o.test
0.0
>>> del o.test
>>> o.test
0.0
속성은 데이터 설명자이므로 일반적인 점선 조회 알고리즘에서 가장 먼저 찾는 것입니다.
옵션 __getattribute__
를 통해 모든 속성에 대한 조회를 절대적으로 구현해야하는 경우 몇 가지 옵션이 있습니다 __getattribute__
.
- raise
AttributeError
, __getattr__
호출되도록 함 (구현 된 경우)
- 그것으로부터 무언가를 돌려 주다
super
부모 (아마도 object
의) 구현 을 호출하는 데 사용
- 부름
__getattr__
- 어떻게 든 자신의 점선 조회 알고리즘 구현
예를 들면 :
class NoisyAttributes(object):
def __init__(self):
self.test=20
self.test2=21
def __getattribute__(self, name):
print('getting: ' + name)
try:
return super(NoisyAttributes, self).__getattribute__(name)
except AttributeError:
print('oh no, AttributeError caught and reraising')
raise
def __getattr__(self, name):
"""Called if __getattribute__ raises AttributeError"""
return 'close but no ' + name
>>> n = NoisyAttributes()
>>> nfoo = n.foo
getting: foo
oh no, AttributeError caught and reraising
>>> nfoo
'close but no foo'
>>> n.test
getting: test
20
원래 원했던 것.
이 예는 원래 원했던 작업을 수행하는 방법을 보여줍니다.
class D(object):
def __init__(self):
self.test=20
self.test2=21
def __getattribute__(self,name):
if name=='test':
return 0.
else:
return super(D, self).__getattribute__(name)
그리고 다음과 같이 작동합니다.
>>> o = D()
>>> o.test = 'foo'
>>> o.test
0.0
>>> del o.test
>>> o.test
0.0
>>> del o.test
Traceback (most recent call last):
File "<pyshell#216>", line 1, in <module>
del o.test
AttributeError: test
코드 검토
주석이있는 코드. 에서 자체에 대한 점선 조회가 __getattribute__
있습니다. 이것이 재귀 오류가 발생하는 이유입니다. 이름이 있는지 확인 하고 해결 방법으로 "__dict__"
사용할 super
수 있지만 __slots__
. 나는 그것을 독자에게 연습으로 남겨 둘 것입니다.
class D(object):
def __init__(self):
self.test=20
self.test2=21
def __getattribute__(self,name):
if name=='test':
return 0.
else: # v--- Dotted lookup on self in __getattribute__
return self.__dict__[name]
>>> print D().test
0.0
>>> print D().test2
...
RuntimeError: maximum recursion depth exceeded in cmp