我试图编写一个decorator,它在被调用后“刷新”,但是刷新只在最后一个函数退出后发生一次。下面是一个例子:
@auto_refresh
def a():
print "In a"
@auto_refresh
def b():
print "In b"
a()
如果调用了a()
,我希望在退出a()
之后运行刷新函数。如果调用b()
,我希望在退出b()
之后运行刷新函数,而不是在由b()
调用时在a()
之后运行。下面是一个类执行此操作的示例:
如果我跑的话
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在第一种和第二种情况下被调用多次,在最后一种情况下调用一次(在第一种和第二种情况下应该是一次,而不是在最后一种情况下)。在
以线程安全的方式计算“嵌套”的数量是使用thread-local storage的一个很好的例子:
如果您不关心线程,只要您的Python安装是在启用线程的情况下编译的(而现在几乎所有这些都启用了),这仍然可以正常工作。如果您担心没有线程的特殊Python安装,请将
^{pr2}$import
语句改为大致如the docs中建议的那样(除了文档对导入结果使用了一个特殊的“private”名称,而且没有真正的原因,所以我使用了一个简单的名称;-)。在
我认为维护一个“嵌套刷新计数”可能更简单,该计数在每次刷新修饰调用之前递增,在每次刷新修饰调用之后递减(在finally块中,这样计数就不会弄乱);每当计数为零时运行刷新例程。在
我不清楚你到底想用这个设计做什么,因此,这是不是个好主意。考虑一下这是否是正确的方法。在
不过,我认为这符合你的要求。一个公共对象(在本例中命名为
auto_refresh
)由所有的“decorated”方法共享,并且该对象保留一个关于调用堆栈深度的计数器。在这不是线程安全的。在
测试方法:
^{pr2}$导致:
相关问题 更多 >
编程相关推荐