我看着尝试构建一个可以与OR一起使用且不带参数(即可以用@deco
或@deco(arg1='x',arg2='y')
调用的装饰器)。但是我在使用参数时遇到了麻烦:如果我取消注释下面的2条注释行,则会得到UnboundLocalError: local variable 'arg1' referenced before assignment
,但是从逻辑上讲,当注释行时也会出现此错误,因为在变量之间未分配任何值。 / p>
def deco(_func=None, *, arg1=False, arg2='default'):
def outer_wrap(func):
def inner_wrap(*args, **kwargs):
# if not arg1:
# arg1 = 'blah'
return 'arg1: '+str(arg1)+', arg2: '+str(arg2)
return inner_wrap
if _func is None: # case when @deco is called with arguments
return outer_wrap
else: # case without arguments
return outer_wrap(_func)
@deco
def I(n):
return n
I(1)
在这里一定有我所缺少的东西,欢迎您帮助我们理解为什么会发生这种情况。 (我使用的是Python 3.8.3)
编辑 由于以下答案,我还通过添加arg1和arg2作为包装函数的参数来修改了代码:
def deco(_func=None, *, arg1=False, arg2='default'):
def outer_wrap(func, arg1=arg1, arg2=arg2):
def inner_wrap( *args, arg1=arg1, arg2=arg2, **kwargs):
if not arg1:
arg1 = 'blah'
return 'arg1: '+str(arg1)+', arg2: '+str(arg2)
return inner_wrap
if _func is None:
return outer_wrap
else:
return outer_wrap(_func)
@deco #can add or remove arguments here
def I(n):
return n
print(I(5))
答案 0 :(得分:0)
注释掉赋值后,arg1
不是内部函数中的 local 变量,因为它是外部函数的参数。
内部函数中的赋值arg1 = 'blah'
使局部变量具有相同的名称,从而在下一行更改arg1
的含义;现在它是内部函数的局部变量,当if
语句的条件为false时,该变量没有赋值,因此Python不再寻找相同名称的其他变量。
此行为在this other Stack Overflow Q&A中有更详细的描述。
答案 1 :(得分:0)
只需完成@ kaya3答案,您就可以代替:
mkdir -p /var/run/mysqld/
chmod 777 /var/run/mysqld/
答案 2 :(得分:0)
这个问题与python中的'Closure'函数有关。闭包是一个函数对象,即使在内存中不存在值时,它也会记住范围内的值。
通过使用arg1=blah
,使其成为内部函数的局部变量。要解决此问题,而不是将arg1用作外部函数参数中具有布尔值arg1=False
的不可更改对象,可以使arg1成为类型为list,set,dict的可变对象。
例如:
enter code here
def deco(_func=None, arg1=[], arg2='default'):
def outer_wrap(func):
def inner_wrap(*args, **kwargs):
if len(arg1) is 0:
arg1.append('blah')
return 'arg1: ' + arg1[0] + ' arg2: ' + str(arg2)
return inner_wrap
if _func is None: # case when @deco is called with arguments
return outer_wrap
else: # case without arguments
return outer_wrap(_func)
@deco
def I(n):
return n
I(1)
您可以在互联网上进一步了解python中的闭包函数。(例如:https://www.openbookproject.net/py4fun/decorator/decorator.html)