데이터 기술자는 클래스 네임 스페이스에 살고있다. 이것들은 2 개의 별도의 사전들입니다. 그래서 여기서 충돌이 없습니다.
그래서 인스턴스
bar
에 이름
foo
에 대한 특정 속성 조회에, 파이썬은 다음 순서로, (아래
C
이름
type(bar)
) 그것의 클래스에 보이는 :
C.foo
가 조회됩니다. 데이터 설명자 인 경우 조회가 종료됩니다. C.foo.__get__(bar, C)
이 리턴됩니다. 그렇지 않으면, 파이썬은 3 단계에서이 결과를 저장할 것입니다.
C.foo
이 존재하지 않거나 일반 속성 인 경우 Python은 bar.__dict__['foo']
을 찾습니다. 존재하는 경우 반환됩니다. C.foo
이 데이터 설명자 인 경우이 부분에 도달하지 않습니다.
bar.__dict__['foo']
이없고 C.foo
이있는 경우 C.foo
이 사용됩니다. C.foo
이 (데이터가 아닌) 설명자 인 경우 C.foo.__get__(bar, C)
이 반환됩니다.
(C.foo
정말 C.__dict__['foo']
이지만, 단순 위해 내가 위의 클래스에 기술자 액세스를 무시 한 것을 참고).
아마도 구체적인 예가 도움이 될 것입니다. 여기에 두 가지 설명이있다, 하나는 데이터 기술자 (A __set__
방법이가)이고, 다른 하나는 하지 데이터 설명 :
>>> class DataDesc(object):
... def __get__(self, inst, type_):
... print('Accessed the data descriptor')
... return 'datadesc value'
... def __set__(self, inst, value):
... pass # just here to make this a data descriptor
...
>>> class OtherDesc(object):
... def __get__(self, inst, type_):
... print('Accessed the other, non-data descriptor')
... return 'otherdesc value'
...
>>> class C(object):
... def __init__(self):
... # set two instance attributes, direct access to not
... # trigger descriptors
... self.__dict__.update({
... 'datadesc': 'instance value for datadesc',
... 'otherdesc': 'instance value for otherdesc',
... })
... datadesc = DataDesc()
... otherdesc = OtherDesc()
...
>>> bar = C()
>>> bar.otherdesc # non-data descriptor, the instance wins
'instance value for otherdesc'
>>> bar.datadesc # data descriptor, the descriptor wins
Accessed the data descriptor
'datadesc value'
데이터 설명자가 클래스 사전에 있습니다. "Descriptor HowTo Guide"는 인스턴스 사전이 클래스 사전 이전에 검색되도록 제안하는 것 같습니다 : "예를 들어, ax는 .__ dict __ [ 'x']로 시작하는 검색 체인을 가지고 있습니다. 그런 다음 (a) .__ dict __ [ 'x'], 그리고 메타 클래스를 제외한 유형 (a)의 기본 클래스를 계속 진행하십시오. " –
@SirVisto는 거기에서 단순화하고 있습니다. 그림에서 데이터 설명자를 가져온 경우 순서가 완벽합니다.그 시점에서 데이터 서술자를 도입하면 이야기가 불필요하게 복잡해집니다. –
사실,이 기사에서는 나중에 설명합니다. "구현은 인스턴스 변수보다 데이터 설명자를 우선시하고 비 데이터 기술자보다 우선 순위가 높은 인스턴스 변수를 제공하고 제공된 경우 __getattr __()에 우선 순위를 최하위로 할당하는 선행 체인을 통해 작동합니다." –