python - 刷新装饰器

标签 python algorithm decorator

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

@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/

相关文章:

algorithm - 从一组三角形计算高氏着色顶点法线的最有效算法

java - Node HMAC 结果不同于 Ruby 和 Java

c - 二分查找...这段代码有问题吗

java - 如何在java运行时更改具体装饰器中的变量

python - 在 Python 3 中,如何创建类似数字的对象?

javascript - 这是WebSocket的正常使用还是低级的使用?

java - 检查单元测试是否委托(delegate)了所有方法

python - 函数如何知道调用函数的装饰器

python - Django 从 models.py 导入类

python - 更改Python中函数的参数