如果我正在使用模块/类,我无法控制,我将如何修饰其中一种方法?如何将装饰器添加到现有的对象方法?
我知道我可以:my_decorate_method(target_method)()
但我希望有这种情况发生,无需进行搜索/替换即可调用target_method
。
这有可能吗?
如果我正在使用模块/类,我无法控制,我将如何修饰其中一种方法?如何将装饰器添加到现有的对象方法?
我知道我可以:my_decorate_method(target_method)()
但我希望有这种情况发生,无需进行搜索/替换即可调用target_method
。
这有可能吗?
是的,这是可能的,但有几个问题。 首先,你明白地从类中得到一个方法,你得到一个修饰器对象,但不是函数本身。
class X(object):
def m(self,x):
print x
print X.m #>>> <unbound method X.m>
print vars(X)['m'] #>>> <function m at 0x9e17e64>
def increase_decorator(function):
return lambda self,x: function(self,x+1)
其次,我不知道,如果设置新的方法将总是工作:
x = X()
x.m(1) #>>> 1
X.m = increase_decorator(vars(X)['m'])
x.m(1) #>>> 2
不要这样做。
使用继承。
import some_module
class MyVersionOfAClass(some_module.AClass):
def someMethod(self, *args, **kwargs):
# do your "decoration" here.
super(MyVersionOfAClass, self). someMethod(*args, **kwargs)
# you can also do "decoration" here.
现在,收拾你的主程序使用MyVersionOfAClass
,而不是some_module.AClass
。
这是我看待这个问题的原始方式,但这是很多工作。接受答案中的方法对知道有用 - 即使它不是最正确的做事方式。 – 2009-09-14 13:20:54
这不是一个“更正确”的问题,而是“可读”和“可维护”问题。你的用例是OO语言继承的确切原因。它可能表现为很多工作,但这是每个其他程序员期望看到的。从长远来看,有趣的动态装饰者是一种责任。普通的旧遗产不会成为一项责任。 – 2009-09-14 16:10:47