假设我有这个装饰者:
def decorator(f):
def f_wrap(*args):
for item in args:
print(args)
return f(*args)
return f_wrap
用作"永久"具有@
语法的装饰器args
检索包装函数的参数。例如,当与下面的类一起使用时,我会收到MyObject
的实例。
Class MyObject(object):
def __init__(self):
pass
@decorator
def function(self):
return
如何使用"流体"来实现相同的结果?装饰。还是装饰者没有永久地绑定到它正在装饰的功能?例如:
def decorator(f):
def f_wrap(*args):
if (not args):
print("Nothing in args")
return f(*args)
return f_wrap
class MyClass(object):
def __init__(self):
pass
def function(self):
return
if __name__ == "__main__":
myobj = MyClass()
myobj.function = decorator(myobj.function)
myobj.function()
在这种情况下,args
元组总是返回空(我总是得到" args&#34中没有任何东西;),即使我预期它会返回实例变量myobj
。
修改:
如果@AChampion的帖子不清楚,解决办法就是简单地将流体装饰的方法称为"未绑定的"方法。如,
from types import MethodType
def decorator(f):
def f_wrap(*args):
# I replaced this with an iteration through
# args. It's a bit more demonstrative.
for item in args:
print(item)
return f(*args)
return f_wrap
class MyClass(object):
def __init__(self):
pass
def function(self):
return
if __name__ == "__main__":
myobj = MyClass()
myobj.function = MethodType(decorator(MyClass.function), myobj)
myobj.function()
答案 0 :(得分:2)
您没有正确使用all
。 all
会在all
中检查的内容中是否符合所有条件,返回一个bool。在你的情况下,你并没有真正做任何事情。您将始终使用all
评估为True。
我相信你所寻找的只是这个:
if not args:
现在,最终检查的是你正在执行的方法是否有* args。对于你所拥有的函数的情况,你没有传递任何参数,因此,通过if not args
检查,你实际上会得到:
"Nothing in args"
但是,如果您为方法添加一个参数:
def function(self, x):
return
然后致电:myobj.function(1)
你不得到" args"
回答您关于未获取实例的最后一个问题。如果您使用这种调用装饰器的方法打印f
:
myobj.function = decorator(myobj.function)
myobj.function()
您将获得绑定方法:
<bound method MyClass.function of <__main__.MyClass object at 0x102002390>>
现在,设置你的装饰师:
@decorator
def function(self):
return
您将看到附加到类对象的函数:
<function MyClass.function at 0x102001620>
因此表明他们并没有做你期望的完全相同的事情。希望这有助于澄清一点。
答案 1 :(得分:2)
区别的原因是你要包装不同的东西,一个未绑定的方法与一个绑定的方法:
class MyObject(object):
@decorator
def function(self):
pass
相当于:
import types
class MyClass(object):
def function(self):
pass
m = MyClass(object)
m.function = types.MethodType(decorator(MyClass.function), m)
不
m.function = decorator(m.function)
第一个是未绑定的方法,第二个是绑定方法。