2012-06-26 4 views
24

"파이썬 속성 조회 프로세스"라고 할 때 : x.foo를 쓸 때 파이썬이하는 일은 무엇입니까 ?? attrname라는이라면 내가 이것에 대해 많은 문서에 발견되지 않은 웹 검색python 속성 조회 프로세스는 어떻게 작동합니까?

, 내가 찾은 최고의 논문 중 하나가 다음 단계로 였는지를 재개

  1. (당신은 전체 기사 here을 볼 수 있습니다) objectname에 특별한 (예 : Python 제공) 속성이 있으면 그것을 돌려줍니다.
  2. attrname의 objectname .__ 클래스 __.__ dict__을 확인하십시오. 존재하고 데이터 - 디스크립터 인 경우, 디스크립터 결과를 리턴한다. 같은 경우에 대해 objectname .__ class__의 모든 기준을 검색하십시오.
  3. attname에 대해 objectname .__ dict__를 확인하고 발견되면 리턴하십시오. objectname이 클래스 인 경우 해당베이스도 검색하십시오. 그것이 클래스이고, 그 또는 그베이스 내에 기술자가 존재하는 경우는, 기술자의 결과를 돌려줍니다.
  4. attrname의 objectname .__ 클래스 __.__ dict__을 확인하십시오. 존재하고 비 데이터 디스크립터 인 경우 디스크립터 결과를 리턴한다. 존재하고 기술자가 아닌 경우 반환하십시오. 그것이 존재하고 데이터 기술자 인 경우, 우리는 2 번 지점으로 돌아 왔을 것이기 때문에 여기에 있으면 안됩니다. objectname .__ class__의 모든 기지를 검색하여 동일한 경우를 찾습니다.
  5. Raise AttributeError.

처음에는 이것이 옳았 겠지만 x.foo의 경우와 같이 속성 조회 프로세스가 조금 더 복잡합니다. x가 클래스 또는 인스턴스 인 경우 동일한 동작을하지 않습니다.

이 방법으로 설명 할 수없는 샘플이 있습니다.

class Meta(type): 
    def __getattribute__(self, name): 
     print("Metaclass getattribute invoked:", self) 
     return type.__getattribute__(self, name) 

    def __getattr__(self, item): 
     print('Metaclass getattr invoked: ', item) 
     return None 

class C(object, metaclass=Meta): 
    def __getattribute__(self, name): 
     print("Class getattribute invoked:", args) 
     return object.__getattribute__(self, name) 

c=C() 

지금 해당 출력에 다음 줄을 확인하십시오 :

>> C.__new__ 
Metaclass getattribute invoked: <class '__main__.C'> 
<built-in method __new__ of type object at 0x1E1B80B0> 

>> C.__getattribute__ 
Metaclass getattribute invoked: <class '__main__.C'> 
<function __getattribute__ at 0x01457F18> 

>> C.xyz 
Metaclass getattribute invoked: <class '__main__.C'> 
Metaclass getattr invoked: xyz 
None 

>> c.__new__ 
Class getattribute invoked: (<__main__.C object at 0x013E7550>, '__new__') 
<built-in method __new__ of type object at 0x1E1B80B0> 

>> c.__getattribute__ 
Class getattribute invoked: (<__main__.C object at 0x01438DB0>, '__getattribute__') 
Metaclass getattribute invoked: <class '__main__.C'> 
<bound method C.__getattribute__ of <__main__.C object at 0x01438DB0>> 

>> 

을 내가 (우리가 x.foo 검색하는 고려)되어왔다 결론 :

다음 파이썬 코드를 고려
  • __getattribute__은 < 유형 'type'> 및 < 유형 'object'> 인스턴스와 다릅니다. C.foo()의 경우 C .__ dict__에서 'foo'가 먼저 검색되고 (C 유형 검색 대신) 발견되면 x.foo() 'foo'가 type (x) .__ dict__에서 검색되고 x .__ dict__에.
  • __getattribute__ 메서드는 항상 유형 (x)에서 처리됩니다. 여기서 마지막으로 이해할 수없는 것은 c :__ getattribute__, __getattribute__ (및 C는 개체에서 상속 된) 메서드가 포함 된 개체가 아니므로 왜 메타 클래스가 getattribute 메소드가 호출됩니다.

누군가 설명해 주시겠습니까 ?? 또는 덜 말해서 내가 이것에 대한 몇 가지 문서를 찾을 수있는 곳, 감사합니다.

답변

4

당신이 print("Metaclass getattribute invoked:", self, name)를 추가 한 경우 당신이 볼 것 :

>>> c.__getattribute__ 
Class getattribute invoked: <__main__.C object at 0x2acdbb1430d0> __getattribute__ 
Metaclass getattribute invoked: <class '__main__.C'> __name__ 
<bound method C.__getattribute__ of <__main__.C object at 0x2acdbb1430d0>> 

C__name__를 인쇄 할 수 있도록 메타 클래스 __getattribute__이 표현 c.__getattribute__repr를 구축하기 위해 호출지고 있습니다.

btw, __getattribute__은 클래스와 메타 클래스에서 동일하게 작동합니다. 속성은 먼저 인스턴스에서 조회 한 다음 인스턴스 유형에서 조회합니다.

>>> Meta.foo = 1 
>>> C.foo 
('Metaclass getattribute invoked:', <class '__main__.C'>, 'foo') 
1 
>>> c.foo 
('Class getattribute invoked:', <__main__.C object at 0x2acdbb1430d0>, 'foo') 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "<stdin>", line 5, in __getattribute__ 
AttributeError: 'C' object has no attribute 'foo' 
>>> C.bar = 2 
>>> c.bar 
('Class getattribute invoked:', <__main__.C object at 0x2acdbb1430d0>, 'bar') 
2 
+2

파이썬 유형 및 객체 http://www.cafepy.com/article/python_types_and_objects/ – amirouche