为什么魔术方法没有被 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。
主题。
示例:
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。