gpt4 book ai didi

python - 刷新装饰器

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:16:49 24 4
gpt4 key购买 nike

我正在尝试编写一个在被调用后“刷新”的装饰器,但刷新仅在最后一个函数退出后发生一次。这是一个例子:

@auto_refresh
def a():
print "In a"

@auto_refresh
def b():
print "In b"
a()

如果调用a(),我希望在退出a() 后运行刷新函数。如果调用 b(),我希望刷新函数在退出 b() 后运行,但在调用时不在 a() 之后运行通过 b()。这是执行此操作的类的示例:

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

因为刷新在第一种和第二种情况下被调用多次,而在最后一种情况下被调用一次(当它应该在第一种和第二种情况下被调用一次,而不是在最后一种情况下)。

最佳答案

以线程安全的方式计算“嵌套”的数量是使用 thread-local storage 的一个很好的例子。 :

import threading
mydata = threading.local()
mydata.nesting = 0

class auto_refresh(object):

def __init__(self, f):
self.f = f

def __call__(self, *args, **kwargs):
mydata.nesting += 1
try: return self.f(*args, **kwargs)
finally:
mydata.nesting -= 1
if mydata.nesting == 0:
print 'refreshing'

如果您不关心线程,只要您的 Python 安装是在启用线程的情况下编译的(现在几乎所有线程都启用了),这仍然可以正常工作。如果您担心没有线程的特殊 Python 安装,请将 import 语句更改为

try:
import threading
except ImportError:
import dummy_threading as threading

大致按照 the docs 中的建议(除了文档为导入结果使用了一个特殊的“私有(private)”名称,而且没有真正的原因,所以我使用了一个普通名称;-)。

关于python - 刷新装饰器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2529592/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com