装饰器的内部函数无法访问装饰器变量

Posted

技术标签:

【中文标题】装饰器的内部函数无法访问装饰器变量【英文标题】:Decorator's inner function not able to access decorator variable 【发布时间】:2020-05-02 22:45:48 【问题描述】:

我有以下代码

from time import sleep
def dec(my_func,*args,**kwargs):
     counter = 0
     def temp_func(*args, **kwargs):
         try:
             my_func(*args,**kwargs)
             return True
         except:
             if counter < 5:
                 counter+=1
                 temp_func(*args, **kwargs)
                 sleep(10)
             else:
                 return False
     return temp_func
@dec
def my_func(a,b):
    return a/b

print(my_func(1,2))
print(my_func(1,0))

它抛出以下错误。

---------------------------------------------------------------------------
UnboundLocalError                         Traceback (most recent call last)
<ipython-input-11-f73a2a9ab2e3> in <module>()
----> 1 my_func(1,0)

<ipython-input-8-bce781eec53d> in temp_func(*args, **kwargs)
      7             return True
      8         except:
----> 9             if counter < 5:
     10                 counter+=1
     11                 temp_func(*args, **kwargs)

UnboundLocalError: local variable 'counter' referenced before assignment

为什么这里的内部函数无法访问装饰器变量?通常,内部函数可以访问装饰器变量。即使我在全局上下文中设置计数器变量,我也会得到同样的错误。我在这里错过了什么吗?

【问题讨论】:

尝试使用你的装饰器作为@dec() 检查this answer是否有帮助 嗯...为什么print(my_func(1, 2))没有发生错误?但无论如何,如果您要将counter 设置为全局(如果这是您想要的),那么请确保将global counter 作为dec 的第一行。 【参考方案1】:

我不完全确定为什么会发生此错误,但如果您将 counter 移动到 temp_func 而不是 dec 则它可以工作。应该有同样的效果。

【讨论】:

以上是关于装饰器的内部函数无法访问装饰器变量的主要内容,如果未能解决你的问题,请参考以下文章

python装饰器的小细节

python函数2_闭包和装饰器

Python的闭包和装饰器

Python函数编程——闭包和装饰器

Watcher 内 Vue 类组件装饰器的访问方法

python 带参与不带参装饰器的使用