2017-01-04 33 views
0

我的問題:爲什麼不調用__getattr__進行索引操作?

似乎__getattr__不叫索引操作,即我不能使用__getattr__上一類A提供A[...]。是否有一個原因?還是一種避開它的方式,以便__getattr__可以提供該功能,而無需在A上明確定義__getitem____setitem__等?

小例子:

比方說,我定義了兩個幾乎相同的類,ExplicitImplicit。每個都在創建時創建一個小列表self._arr,並且每個都定義了一個__getattr__,它將所有屬性請求傳遞給self._arr。唯一的區別是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

因爲這就是Python的設計原理。 '__getattr__'用於屬性訪問,'__getitem__'用於索引訪問。每個人都有特定的角色。我不確定這個問題是什麼 – 3Doubloons

+1

[This answer](http://stackoverflow.com/a/10376655/2096752)解釋它。 – shx2

+2

至於爲什麼他們是單獨的操作,請考慮這一點:'d = {'keys':0}'在這種情況下,'d.keys'和'd ['keys']'是非常不同的東西 – 3Doubloons

回答

1

的Python繞過__getattr____getattribute__和實例字典實施語言機制。 (大多數情況下,特殊方法是在名稱的每一側都帶有兩個下劃線的方法。)如果您期待i[0]調用i.__getitem__(0),這又會調用i.__getattr__('__getitem__')(0),這就是爲什麼沒有發生。

+1

對於任何人來說,上面的@ shx2的評論鏈接到[與此有關的參考問題](http://stackoverflow.com/a/10376655/2096752)。 –

相關問題