为什么这个变量会产生 UnboundLocalError?

Why is this variable creating an UnboundLocalError?

我正在尝试创建一个包装器,它使用参数的函数名称和字符串表示来创建缓存键。

我尝试了以下方法,但由于某种原因我得到了 NameError

>>> def cache_key_gen(func):
...     key = func.__name__
...     def wrapper(*args):
...             global key
...             print(key)
...             for arg in args:
...                     key += str(arg)
...             print(key)
...             return func(*args)
...     return wrapper
...
>>> @cache_key_gen
... def add(x, y):
...     return  x + y
...
>>> add(1,2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in wrapper
NameError: name 'key' is not defined

当我尝试以下操作时,我得到 UnboundLocalError

>>> def cache_key_gen(func):
...     key = func.__name__
...     def wrapper(*args):
...             for arg in args:
...                     key += str(arg)
...             print(key)
...             return func(*args)
...     return wrapper
...
>>> @cache_key_gen
... def add(x, y):
...     return  x + y
...
>>> add(1,2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in wrapper
UnboundLocalError: local variable 'key' referenced before assignment

我很困惑,我错过了什么。这似乎是一个基本的愚蠢错误,或者是我不知道的关于装饰器的一些行为。

key 不是全局的;它是 nonlocal,在 cache_key_gen.

中定义
def cache_key_gen(func):
...     key = func.__name__
...     def wrapper(*args):
...             <b>nonlocal</b> key
...             print(key)
...             for arg in args:
...                     key += str(arg)
...             print(key)
...             return func(*args)
...     return wrapper