Why is __getattr__ not called for indexing operations?

回眸只為那壹抹淺笑 提交于 2019-12-01 12:48:23

问题


My question:

It seems that __getattr__ is not called for indexing operations, ie I can't use __getattr__ on a class A to provide A[...]. Is there a reason for this? Or a way to get around it so that __getattr__ can provide that functionality without having to explicitly define __getitem__, __setitem__, etc on A?

Minimal Example:

Let's say I define two nearly identical classes, Explicit and Implicit. Each creates a little list self._arr on initiation, and each defines a __getattr__ that just passes all attribute requests to self._arr. The only difference is that Explicit also defines __getitem__ (by just passing it on to 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)

This works as expected:

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

But this doesn't:

>>> 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:


Python bypasses __getattr__, __getattribute__, and the instance dict when looking up "special" methods for implementing language mechanics. (For the most part, special methods are ones with two underscores on each side of the name.) If you were expecting i[0] to invoke i.__getitem__(0), which would in turn invoke i.__getattr__('__getitem__')(0), that's why that didn't happen.



来源:https://stackoverflow.com/questions/41471594/why-is-getattr-not-called-for-indexing-operations

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!