元类在这里无济于事;尽管会根据当前对象的类型(例如实例的类)查找特殊方法,
__getattribute__或者
__getattr__在这样做时不对其进行查询(可能是因为它们本身就是特殊方法)。因此,要捕获
所有 dunder方法,您必须全部创建它们。
你可以得到所有的一个相当不错的清单 运营商
的特殊方法(
__pow__,
__gt__等)通过枚举
operator模块:
import operatoroperator_hooks = [name for name in dir(operator) if name.startswith('__') and name.endswith('__')]有了该列表,类装饰器可以是:
def instrument_operator_hooks(cls): def add_hook(name): operator_func = getattr(operator, name.strip('_'), None) existing = getattr(cls, name, None) def op_hook(self, *args, **kw): print "Hooking into {}".format(name) self._function = operator_func self._params = (args, kw) if existing is not None: return existing(self, *args, **kw) raise AttributeError(name) try: setattr(cls, name, op_hook) except (AttributeError, TypeError): pass # skip __name__ and __doc__ and the like for hook_name in operator_hooks: add_hook(hook_name) return cls然后将其应用于您的班级:
@instrument_operator_hooksclass CatchAll(object): pass
演示:
>>> c = CatchAll()>>> c ** 2Hooking into __pow__Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 11, in op_hookAttributeError: __pow__>>> c._function<built-in function pow>>>> c._params((2,), {})因此,即使我们的类没有
__pow__明确定义,我们仍然会迷上它。



