【发布时间】:2010-03-27 14:22:05
【问题描述】:
我正在尝试编写一个在被调用后“刷新”的装饰器,但在最后一个函数退出后刷新只发生一次。这是一个例子:
@auto_refresh
def a():
print "In a"
@auto_refresh
def b():
print "In b"
a()
如果调用a(),我希望在退出a()后运行刷新功能。如果调用了b(),我希望在退出b() 之后运行刷新功能,而不是在b() 调用时在a() 之后运行。这是执行此操作的类的示例:
class auto_refresh(object):
def __init__(self, f):
print "Initializing decorator"
self.f = f
def __call__(self, *args, **kwargs):
print "Before function"
if 'refresh' in kwargs:
refresh = kwargs.pop('refresh')
else:
refresh = False
self.f(*args, **kwargs)
print "After function"
if refresh:
print "Refreshing"
使用这个装饰器,如果我运行
b()
print '---'
b(refresh=True)
print '---'
b(refresh=False)
我得到以下输出:
Initializing decorator
Initializing decorator
Before function
In b
Before function
In a
After function
After function
---
Before function
In b
Before function
In a
After function
After function
Refreshing
---
Before function
In b
Before function
In a
After function
After function
因此,以这种方式编写时,不指定refresh 参数意味着刷新默认为False。任何人都可以想出一种方法来改变这一点,以便refresh 在未指定时为True?改变
refresh = False
到
refresh = True
在装饰器中 不 工作:
Initializing decorator
Initializing decorator
Before function
In b
Before function
In a
After function
Refreshing
After function
Refreshing
---
Before function
In b
Before function
In a
After function
Refreshing
After function
Refreshing
---
Before function
In b
Before function
In a
After function
Refreshing
After function
因为 refresh 在第一种和第二种情况下被调用多次,在最后一种情况下被调用一次(在第一种和第二种情况下应该调用一次,而不是在最后一种情况下)。
【问题讨论】:
-
“刷新一个装饰器”?为什么你有有状态的装饰器?这非常非常令人困惑。您是否正在尝试创建某种可调用对象?
-
刷新可以是例如用于显示 - 所以你可以想象一个 GUI 程序,你不想在每次函数调用后刷新,但你想在函数的“树”被调用后刷新,无论启动函数是什么。
-
这不是装饰器的用途。这就是适当的 GUI 对象的用途。有状态的装饰器是一个非常令人困惑的想法,它与装饰器的普通用途根本不同,以至于成为维护的噩梦。
-
在我的情况下,我无法控制 GUI 代码 - 我必须强制 GUI 刷新,但要防止每个函数调用多次刷新。
标签: python algorithm decorator