Python:强制装饰器继承吗?

Phi*_*ham 5 python inheritance decorator

我正在使用相当大的OOP代码库,我想注入一些跟踪/日志记录。最简单的方法是在一些基类的某些方法周围引入一个装饰器,但是不幸的是装饰器没有被继承。

我确实尝试过以下操作:

def trace(fn):
    def wrapper(instance, *args, **kwargs):
        result = fn(instance, *args, **kwargs)
        # trace logic...
        return result
    return wrapper

class BaseClass(object):
    def __init__(self, ...):
        ...
        self.__call__ = trace(self.__call__)  # line added to end of method
Run Code Online (Sandbox Code Playgroud)

...并且当__call__方法包裹(我可以从印刷实例信息发送到控制台看到)的wrapper预期不执行功能。

我还简要地研究了基于此答案的元类,但是它立即破坏了使用自省的系统其他部分,因此我认为这是不可行的。

还有其他方法可以强制这些装饰器围绕__call__从其继承的类的方法应用BaseClass吗?

fre*_*ish 4

为什么元编程会扰乱内省?也许你没有正确使用它?试试这个(假设Python2.x):

class MyMeta(type):
    def __new__(mcl, name, bases, nmspc):
        if "__call__" in nmspc:
            nmspc["__call__"] = trace(nmspc["__call__"])
        return super(MyMeta, mcl).__new__(mcl, name, bases, nmspc)

class BaseClass(object):
    __metaclass__ = MyMeta
Run Code Online (Sandbox Code Playgroud)

然后,您可以简单地继承BaseClass__call__自动包装。

我不确定什么样的内省会打破这一点。除非BaseClass实际上不是继承自object而是继承自实现自己元的东西?但是您也可以通过强制MyMeta从父级的元(而不是type)继承来处理这种情况。