动态添加装饰器到类

时间:2013-04-11 21:30:44

标签: python pyqt pyqt4 decorator python-decorators

我有一个相当大的参与decorator to debug PyQt signals,我想动态添加到一个类。有没有办法动态地将装饰器添加到类中?

我可能会从错误的角度处理这个问题,所以这就是我想要完成的事情。

目标

  1. 我有一个装饰器,可以发现/附加到类中的所有pyqt信号,并在发出这些信号时打印调试。
  2. 这个装饰器非常适合调试单个类的信号。但是,可能有一段时间我想在应用程序中附加所有信号。这可用于查看我是否在意外时间发出信号等。
  3. 我想动态地将这个装饰器连接到我的所有有信号的类。
  4. 可能的解决方案/想法

    到目前为止,我已经考虑了几种可能的解决方案:

    1. 继承:如果我的所有类都具有相同的基类(除了Python的内置object和PyQt的内置QtCore.QObject之外),这将很容易。我想我可以将这个装饰器附加到我的基类,一切都会按预期运行。但是,在这个特定的应用中并非如此。我不想将所有类更改为具有相同的基类。
    2. Monkey-patch Python objectQtCore.QObject:我不知道这实际上是如何工作的。但是,从理论上讲,我可以将其中一个基类“__init__更改为我在装饰器中定义的new_init吗?这看起来真的很危险,而且可能是好的方式?
    3. 元类:我不认为元类在这种情况下会起作用,因为我必须动态地将__metaclass__属性添加到我想要将装饰器注入的类中。我认为这是不可能的,因为要插入此属性,必须已经构造了类。因此,我定义的任何元类都不会被调用。这是真的?
    4. 我尝试了一些元类魔法的变种,但似乎没有任何效果。我觉得使用元类可能是实现我想要的方式,但我似乎无法让它工作。

      同样,我可能会认为这一切都错了。基本上我想将上面引用的装饰器中的行为附加到我的应用程序中的所有类(甚至可能是选择类的列表)。另外,如果有必要,我可以重构我的装饰师。如果我用装饰器或其他机制附加此行为,我真的不在乎。我只是假设这个装饰器已经完成了我想要的单个类,所以可能很容易扩展。

1 个答案:

答案 0 :(得分:8)

装饰器只不过是自动应用的callables。要手动应用它,请使用装饰器的返回值替换该类:

import somemodule

somemodule.someclass = debug_signals(somemodule.someclass)

这会将somemodule.someclass名称替换为debug_signals的返回值,我们已通过原始somemodule.someclass类。