我知道如何在装饰器中使用本地定义的函数。我在下面的decorator1
中执行此操作。
但是,我发现它并不干净,而且我遇到了酸洗问题。
我希望我的装饰器返回一个可调用的对象。但是,我遇到了问题:如果我执行以下代码
def decorator1(f):
def wrapped(*args,**kwargs):
print(f,' is being called with ',args,kwargs)
return f(*args,**kwargs)
return wrapped
def decorator2(f):
return Wrapped(f)
class Wrapped():
def __init__(self,f):
self.f=f
def __call__(self,*args,**kwargs):
print(self.f,' is being called with ',args,kwargs)
return self.f(*args,**kwargs)
class A():
@decorator1
def foo1(self,x):
return x+1
@decorator2
def foo2(self,x):
return x+1
a=A()
a.foo1(0)
a.foo2(0)
我得到了
<function A.foo1 at 0x7efe64641f28> is being called with (<__main__.A object at 0x7efe65b3b3c8>, 0) {}
<function A.foo2 at 0x7efe6464c0d0> is being called with (0,) {}
Traceback (most recent call last):
File "/home/wolfersf/Dropbox/Professional/Projects/swutil/swutil/test.py", line 28, in <module>
a.foo2(0)
File "/home/wolfersf/Dropbox/Professional/Projects/swutil/swutil/test.py", line 15, in __call__
return self.f(*args,**kwargs)
TypeError: foo2() missing 1 required positional argument: 'x'
似乎a
未在*args
的{{1}}中传递。
我原以为<Wrapped_instance>.__call__
转换为a.foo2(0)
转换为<a.foo2>(a,0)
转换为<Wrapped_instance>(a,0)
转换为<Wrapped_instance>.__call__(a,0)
我做错了什么?
答案 0 :(得分:2)
覆盖__get__
如下作业,但我仍然不确定为什么我的原始尝试失败。
class Wrapped():
def __init__(self,f):
self.f=f
def __call__(self,*args,**kwargs):
print(self.f,' is being called with ',args,kwargs)
return self.f(*args,**kwargs)
def __get__(self,obj,type=None):
return functools.partial(self,obj)