2016-08-19 2 views
0

파이썬의 객체 속성 조회 (여기서는 https://blog.ionelmc.ro/2015/02/09/understanding-python-metaclasses/#object-attribute-lookup)에서 약간 읽었습니다. 내 질문은 두 사람이 동일한 dibe 안되어있다파이썬 3 __getattribute__ 대 도트 액세스 동작

class A: 
    def __getattr__(self, attr): 
     return (1,2,3) 

a = A() 

a.foobar #returns (1,2,3) as expected 
a.__getattribute__('foobar') # raises AttributeError 

:

내가 (python3를) 그것을 밖으로 시도, 그래서 꽤 똑바로 앞으로 것 같은데?

왜 두 번째 속성 오류가 발생합니까?

분명히 대답은 a.foobar의 논리가 a.__getattribute("foobar")의 논리와 다릅니다. data model에 따르면 a.__getattribute("foobar")를 호출하고이 AttributeError를 제기하는 경우, 그것은

a.-__getattr__('foobar')가 그래서 기사가 자신의 그림에서 실수를 것 같다 호출 a.foobar. 이 올바른지?

또 다른 질문 : a.foobar에 대한 실제 논리는 어디에 있습니까? 나는 그것이 __getattribute__에있다라고 생각했다. 그러나 명백하게 전체로.

편집 : 하지

Difference between __getattr__ vs __getattribute__의 중복. object.fooobject.__getattribute__("foo")의 차이점은 무엇입니까? 이것은 __getattr____getatribute__와는 조금 다른데 ...

+1

먼저 공식 문서를 참조하십시오 : https://docs.python.org/3.5/reference/datamodel.html#object.__getattribute__ – thodnev

+0

'.__ getattribute __ ('foobar')'를'a .__ getattr __ ('foobar ')'그리고 무슨 일이 일어나는 지보십시오. – DeepSpace

+0

그 일에 관심이 없다 ...'__getattribute__'는 결국'__getattr__'을 호출하기로되어 있습니다. 'a.foobar'는'__getattribute__'를 호출해야합니다 – deller

답변

4

__getattribute__은 실제로 그 이상을 담당한다는 인상을 받기 쉽습니다. thing.attrthing.__getattribute__('attr')으로 직접 변환되지 않으며 __getattribute____getattr__을 호출 할 책임이 없습니다.

__getattr__에 대한 폴백은 __getattribute__ 외부에있는 특성 액세스 장치 부분에서 발생합니다. 속성 조회 프로세스는 다음과 같이 작동합니다

  • 가의 직접 검색을 통해 __getattribute__ 방법을 찾으 일반 속성 조회 과정을 거치지 않고 객체의 유형의 MRO.
  • 시도 __getattribute__.
    • __getattribute__이 반환되면 속성 조회 프로세스가 완료되며 이는 속성 값입니다.
    • __getattribute__이 AttributeError가 아닌 경우 특성 조회 프로세스가 완료되고 예외가 조회 밖으로 전파됩니다.
    • 그렇지 않으면 __getattribute__이 AttributeError를 발생시킵니다. 조회가 계속됩니다.
  • __getattribute__과 같은 방법으로 __getattr__ 메서드를 찾습니다.
    • __getattr__이 없으면 속성 조회 프로세스가 완료되고 __getattribute__의 AttributeError가 전파됩니다.
  • __getattr__을 시도하고 __getattr__이 반환하거나 제기 한 내용을 반환하거나 제기하십시오.

적어도 언어 의미론면에서 볼 때이 기능은 다음과 같이 작동합니다. 저수준 구현 측면에서, 이러한 단계 중 일부는 불필요한 경우에 최적화 될 수 있으며 설명하지 않은 tp_getattro과 같은 C 후크가 있습니다. CPython 인터프리터 소스 코드를 배우고 싶지 않으면 그런 종류의 것에 대해 걱정할 필요가 없습니다.

+0

TL; DR'__getattribute__ '는 그것이 정의되고'__getattr__'을 호출 할 의도가없는 경우에만 일반 속성 룩업을 바이 패스한다. '__getattribute__'를 정의하지 않은 클래스에서 직접 호출하면'object .__ getattribute__' 또는 다른 기본 클래스로 되돌아 가서 (아마도) 'AttributeError'를 발생시킵니다. –