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

Why magic methods are not intercepted by __getattr__ implementation in python?

主题。

示例:

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’ object does not support indexing

同时:

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

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

在我看来,考虑到 "implementing own container types via composition not inheritance" 的情况,__getattr__ 拦截魔法方法会很有帮助。为什么 python 不支持这样的 "interception"?

要获得完整答案,您需要查看 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 __getattribute__() 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).

请注意,这仅适用于新式 classes(classes 扩展 object),但您确实应该始终使用新式 class es 用于任何新代码。

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