为什么魔术方法没有被python中的__getattr__实现拦截?

主题

例:

MyList(object):

    def __init__(self, list_to_be_wrapped):
          self._items = list_to_be_wrapped

    def __getattr__(self, item):
          return getattr(self._items, item)

然后

MyList([1, 2, 3])[-1]

将引发:TypeError:“ MyList”对象不支持索引

而:

MyList([1, 2, 3]).pop()

会完美运行(pop将被__getattr__拦截并重定向到_items)

在我看来,考虑到“通过组合而不是继承来实现自己的容器类型”的情况,__ getattr__拦截魔术方法将非常有帮助.为什么python不支持这种“拦截”?

解决方法:

要获得完整答案,您需要查看documentation for special method lookup,特别是:

In addition to bypassing any instance attributes in the interest of
correctness, implicit special method lookup generally also bypasses
the 07001 method even of the object’s metaclass.

这是有道理的:

Bypassing the __getattribute__() machinery in this fashion provides
significant scope for speed optimisations within the interpreter, at
the cost of some flexibility in the handling of special methods (the
special method must be set on the class object itself in order to be
consistently invoked by the interpreter).

请注意,这仅适用于新样式类(扩展对象的类),但对于任何新代码,您始终应始终使用新样式类.

最简单的解决方案是,您需要手动代理所有希望重定向到代理类的特殊方法.

上一篇:在Python中,Pandas.如何通过WOM-“每月一周”对数据帧进行子集化?


下一篇:MySQL NULL值的基数