【发布时间】:2011-05-10 13:17:56
【问题描述】:
我需要装饰一个对象的方法。它需要在运行时,因为应用于对象的装饰器取决于用户在调用程序时提供的参数(argv 提供的参数),因此同一对象可以被装饰 3 次、2 次或不被装饰全部。
这里有一些上下文,该程序是一个解谜程序,主要行为是自动找到解谜的解决方案,自动我的意思是无需用户干预。这就是装饰发挥作用的地方,我想做的一件事是绘制执行期间发生的事情的图表,但我只想在使用标志 --draw-graph 时这样做。
这是我尝试过的:
class GraphDecorator(object):
def __init__(self, wrappee):
self.wrappee = wrappee
def method(self):
# do my stuff here
self.wrappee.method()
# do more of stuff here
def __getattr__(self,attr):
return getattr(self.wrappee,attr)
以及为什么它不起作用: 由于我构建应用程序的方式,它不起作用,当我的 Decorator 类中不存在的方法被调用时,感觉回到了装饰类的实现,问题是应用程序总是开始调用方法 @987654325 @ 不需要装饰,所以使用了未装饰的回退,并且从未装饰的表单内部它总是调用 undecorated 方法,我需要的是替换对象中的方法,而不是代理它:
# method responsible to replace the undecorated form by the decorated one
def graphDecorator(obj):
old_method = obj.method
def method(self):
# do my stuff here
old_method()
# do more of my stuff
setattr(obj,'method',method) # replace with the decorated form
这是我的问题,装饰表单在被调用时没有收到self,因为参数数量错误而导致 TypeError。
【问题讨论】:
-
Space_C0wb0y - 我对
__getattr__有疑问,A 类是由 B 类修饰的类,A 有一个调用方法 do() 的方法 run(),B 类修饰了方法 do(),但是因为我在 run() 中使用递归并且我从类 A 方法的 run() 启动它,所以它调用它自己的 do() 版本,而不是修饰的版本。 -
你的问题可以做一些澄清,但如果我没看错,你想“破解”另一个模块中的一些已经编写的代码,以便它实例化一个修改过的对象而不是它通常使用。如果是这样,this answer 会告诉你一种方法。
标签: python python-3.x runtime decorator