【发布时间】:2016-06-02 06:28:25
【问题描述】:
假设我有这个装饰器:
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 元组总是返回空(我总是得到“Nothing in args”),尽管我预计它会返回实例变量 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()
【问题讨论】:
-
你确定你的条件是正确的
all(args)将返回 False 与任何不可证伪的参数,例如0.你只是想要args的len吗?造成差异的原因是第二个实例有一个bound函数(打印出f),而第一个实例只是传入了一个未绑定的函数。