为什么没有为索引操作调用__getattr__?

时间:2017-01-04 19:15:27

标签: python getattr

我的问题:

似乎__getattr__没有调用索引操作,即我无法在类__getattr__上使用A来提供A[...]。是否有一个原因?或者是一种解决方法,以便__getattr__可以提供该功能而无需在__getitem__上明确定义__setitem__A等?

最小示例:

假设我定义了两个几乎相同的类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

1 个答案:

答案 0 :(得分:3)

Python在查找实现语言机制的“特殊”方法时绕过__getattr____getattribute__和实例dict。 (在大多数情况下,特殊方法是在名称的每一侧都有两个下划线的方法。)如果您希望i[0]调用i.__getitem__(0),而i.__getattr__('__getitem__')(0)将调用class SearchItem { public string Category { get; set; } public string SubCategory { get; set; } public string Description { get; set; } public double SalePrice { get; set; } public IList<SearchFilter> Filters { get; set; } } class SearchFilter { public string Group { get; set; } public string Attribute { get; set; } } ,那就是为什么没有发生。