How to decorate all methods in a class? Can I just decorate the class?
本问题已经有最佳答案,请猛点这里访问。
我有几个类,它们有相同的实现名,但实现不同。我想在一些类中装饰所有方法,但其他类不想。我考虑过继承,但是有些类有一些方法不需要修饰。问题是,我不想一个接一个地装饰方法,有些类需要由同一个装饰器来装饰,有没有解决办法?
您可以启动所有需要用一些前缀修饰的方法,然后使用类似这样的方法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | class Xobject(object): def __init__(self, decorator): for method_name in dir(self): if method_name.startswith("dec_"): attr = getattr(self, method_name) wrapped = decorator(attr) setattr(self, method_name, wrapped) def dec_me_1(self): print("In dec_me1") return 0 def dec_me_2(self): print("In dec_me2") return 1 def decorator(func): def wrapped(*args): print("TEST") return func(*args) return wrapped x = Xobject(decorator) x.dec_me_1() x.dec_me_2() |
更新:
您可以通过下面的函数来装饰类。使用python时,您应该知道python中的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | def decorator(func): def wrapped(*args): print("TEST") return func(*args) return wrapped def decorate_object(p_object, decorator): for method_name in dir(p_object): if method_name.startswith("dec_"): attr = getattr(p_object, method_name) wrapped = decorator(attr) setattr(p_object, method_name, wrapped) decorate_object(Xobject, decorator) x = Xobject() x.dec_me_1() x.dec_me_2() |
您也可以用同样的方式装饰已经实例化的对象:
1 2 3 4 5 6 7 8 9 | x = Xobject() x.dec_me_1() x.dec_me_2() decorate_object(x, decorator) x.dec_me_1() x.dec_me_2() |
在某种程度上,你必须明确什么会被包装,什么不会。
如果我理解正确,我想你可以这样做:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | def wrapper(func): def inner(*args, **kwargs): print"%s was called" func.__name__ return func(*args, **kwargs) return inner class A(object): def foo(self): print"foo called" def bar(self): print"BAR CALLED" class B(A): @wrapper def foo(self): super(B, self).foo() class C(A): @wrapper def bar(self): super(C, self).bar() Stick = A() Dave = B() Jupiter = C() Jupiter.foo() #prints"foo called" Jupiter.bar() #prints"bar wrapped" and"BAR CALLED" |
我相信有几种方法可以解决这个问题,但主要的选择是:
- 创建一个自定义元类,其中
__new__ 方法遍历属性字典,标识方法并对它们进行修饰。参见http://eli.thegreenplace.net/2011/08/14/python-metaclasses-by-example/了解python元类编程的示例。缺点:这可能比我们想进入这里要复杂得多。 - 在常规类的
__init__ 方法中也要这样做。缺点:它只修饰实例方法,而不是类或静态方法,而且速度较慢,因为它在每次创建新实例时都会运行。 课外活动:
1
2
3
4
5
6class Foo(object):
def bar(self):
print 'bar'
for name, ref in vars(Foo):
if callable(ref): ...缺点:你只有一次机会做得对:在进口的时候。子类不会被修改。
在类级修饰器中进行。和在课堂外做同样的缺点(我想)。