Python关闭函数失去外部变量访问
我刚刚学会了python @ decorator,它很酷,但很快我发现我的修改代码出现了奇怪的问题。
def with_wrapper(param1):
def dummy_wrapper(fn):
print param1
param1 = 'new'
fn(param1)
return dummy_wrapper
def dummy():
@with_wrapper('param1')
def implementation(param2):
print param2
dummy()
我调试它,它抛出了在打印参数1异常
UnboundLocalError: local variable 'param1' referenced before assignment
如果我删除了param1 = 'new'
这一行,而没有对外部变量的变量进行任何修改操作(链接到新对象),这个例程可能会起作用。
这是否意味着我只做了一个外部范围变量的副本,然后进行修改?
感谢德尔南,关键是必不可少的。 从这里可能回答:与X语言关闭相比,Python中的闭包有哪些限制?
类似的代码:
def e(a):
def f():
print a
a = '1'
f()
e('2')
而且这也是以前令人讨厌的全球变数:
a = '1'
def b():
#global a
print a
a = '2'
b()
这通过添加全局符号来解决。 但是关闭,没有找到这样的符号。 感谢unutbu,Python 3给了我们非本地的。
我知道从上面直接访问外层变量是只读的。 但是看到前面的阅读变量(print var)也受到影响会感到不舒服。
当Python解析一个函数时,它会在每次找到一个赋值左侧的变量时记录下来,例如
param1 = 'new'
它假设所有这些变量都是该函数的局部变量。 所以当你在这个任务之前
print param1
发生错误是因为在print语句执行时,Python没有为这个局部变量赋值。
在Python3中,你可以通过声明param1
非本地来解决这个问题:
def with_wrapper(param1):
def dummy_wrapper(fn):
nonlocal param1
print param1
param1 = 'new'
fn(param1)
return dummy_wrapper
在Python2中,你必须使用一种技巧,例如在列表(或其他可变对象)中传递param1:
def with_wrapper(param1_list):
def dummy_wrapper(fn):
print param1_list[0]
param1_list[0] = 'new' # mutate the value inside the list
fn(param1_list[0])
return dummy_wrapper
def dummy():
@with_wrapper(['param1']) # <--- Note we pass a list here
def implementation(param2):
print param2
您可以在函数中分配param1
,这使param1
成为局部变量。 但是,它在打印时尚未分配,因此出现错误。 Python不会回退寻找外部作用域中的变量。
方便临时情况或探索性代码(但不是很好的做法) :
如果你想在Python 2.x中从外部范围捕获一个变量,那么使用全局也是一个选择(通常的附带条件)。
虽然下面的内容会抛出(在inner内部赋值outer1使得它在本地,因此在if条件下是无界的):
def outer():
outer1 = 1
def inner():
if outer1 == 1:
outer1 = 2
print('attempted to accessed outer %d' % outer1)
这不会:
def outer():
global outer1
outer1 = 1
def inner():
global outer1
if outer1 == 1:
outer1 = 2
print('accessed outer %d' % outer1)
链接地址: http://www.djcxy.com/p/51251.html