2017-01-04 4 views
0

내 질문은 :인덱싱 작업을 위해 __getattr__이 호출되지 않는 이유는 무엇입니까?

__getattr__이 인덱싱 작업을 위해 호출되지 않습니다 즉, 내가 A[...]을 제공하는 클래스 A__getattr__을 사용할 수 없습니다 것 같다. 이것에 대한 이유가 있습니까? 또는 이 A__getitem__, __setitem__ 등을 명시 적으로 정의하지 않고도 해당 기능을 제공 할 수 있도록 주위를 둘러 볼 방법입니까?

최소 예 :

의 내가 거의 동일한 두 개의 클래스, ExplicitImplicit을 정의한다고 가정 해 봅시다. 각각 개시시 작은 목록 self._arr을 만들고 각 속성은 self._arr으로 모든 속성 요청을 전달하는 __getattr__을 정의합니다. 유일한 차이점은 Explicit__getitem__을 정의한다는 것입니다 (그냥 self._arr으로 전달 함).

# Passes all attribute requests on to a list it contains 
class Explicit(): 
    def __init__(self): 
     self._arr=[1,2,3,4] 
    def __getattr__(self,attr): 
     print('called __getattr_') 
     return getattr(self._arr,attr) 
    def __getitem__(self,item): 
     return self._arr[item] 

# Same as above but __getitem__ not defined 
class Implicit(): 
    def __init__(self): 
     self._arr=[1,2,3,4] 
    def __getattr__(self,attr): 
     print('called __getattr_') 
     return getattr(self._arr,attr) 

이 예상대로 작동합니다

>>> e=Explicit() 
>>> print(e.copy()) 
called __getattr_ 
[1, 2, 3, 4] 
>>> print(hasattr(e,'__getitem__')) 
True 
>>> print(e[0]) 
1 

하지만이되지 않습니다 :

>>> i=Implicit() 
>>> print(i.copy()) 
called __getattr_ 
[1, 2, 3, 4] 
>>> print(hasattr(i,'__getitem__')) 
called __getattr_ 
True 
>>> print(i.__getitem__(0)) 
called __getattr_ 
1 
>>> print(i[0]) 
TypeError: 'Implicit' object does not support indexing 
+6

파이썬이 어떻게 설계 되었기 때문입니다. '__getattr__'는 속성 액세스에 사용되며'__getitem__'은 색인 액세스에 사용됩니다. 각각은 특정한 역할을합니다. 질문이 무엇인지 모르겠습니다. – 3Doubloons

+1

[이 답변] (http://stackoverflow.com/a/10376655/2096752)에서 설명합니다. – shx2

+2

d = { 'keys': 0}'이 경우,'d.keys'와'd [ 'keys']'는 매우 다른 것들입니다. – 3Doubloons

답변

1

파이썬은 __getattr__ 우회, __getattribute__ 및 인스턴스 DICT을 "특별한"방법에 대한 찾을 때 언어 역학을 구현합니다. (대부분의 경우 특수 메서드는 이름의 양쪽에 밑줄이 두 개인 경우입니다.) i[0]i.__getitem__(0)을 호출하여 차례로 i.__getattr__('__getitem__')(0)을 호출 할 것으로 예상되는 경우 그 이유가 발생하지 않습니다.

+1

누구나 볼 수있는 위의 @shx2의 주석은 [이것에 대한 참고 자료가있는 질문] (http://stackoverflow.com/a/10376655/2096752) 링크로 연결됩니다. –