考虑这个小例子:import datetime as dtclass Timed(object): def __init__(self, f): self.func = f def __call__(self, *args, **kwargs): start = dt.datetime.now() ret = self.func(*args, **kwargs) time = dt.datetime.now() - start ret["time"] = time return retclass Test(object): def __init__(self): super(Test, self).__init__() @Timed def decorated(self, *args, **kwargs): print(self) print(args) print(kwargs) return dict() def call_deco(self): self.decorated("Hello", world="World")if __name__ == "__main__": t = Test() ret = t.call_deco()哪个打印Hello(){'world': 'World'}为什么self参数(应该是Test obj实例)没有作为第一个参数传递给装饰函数decorated?如果我手动进行操作,例如:def call_deco(self): self.decorated(self, "Hello", world="World")它按预期工作。但是,如果我必须事先知道某个函数是否装饰,它就破坏了装饰器的全部目的。这里的模式是什么,还是我误会了什么?
3 回答

慕码人2483693
TA贡献1860条经验 获得超9个赞
您首先必须了解函数如何成为方法以及如何self“自动”注入。
一旦知道这一点,“问题” 就很明显了:您正在decorated用Timed实例装饰函数-IOW Test.decorated是Timed实例,而不是function实例-并且您的Timed类不会模仿协议的function类型实现descriptor。您想要的内容如下所示:
import types
class Timed(object):
def __init__(self, f):
self.func = f
def __call__(self, *args, **kwargs):
start = dt.datetime.now()
ret = self.func(*args, **kwargs)
time = dt.datetime.now() - start
ret["time"] = time
return ret
def __get__(self, instance, cls):
return types.MethodType(self, instance, cls)
添加回答
举报
0/150
提交
取消