gpt4 book ai didi

python - 未绑定(bind)本地错误 : local variable referenced before assignment in python closure

转载 作者:太空狗 更新时间:2023-10-30 01:07:39 25 4
gpt4 key购买 nike

我在 Python 中实现了两个简单的闭包。在我看来,它们看起来一样,但一个有效,另一个无效。

工作的是:

def makeInc(x, y):
def inc():
return y + x
return inc

inc5 = makeInc(5, 10)
inc10 = makeInc(10, 5)

inc5 () # returns 15
inc10() # returns 15

但是第二个不起作用:

import os
def linker(dest, filename):
print filename
def link():
if os.path.isfile(filename): # line 17
filename = os.path.join(os.getcwd(), filename)
dest = os.path.join(dest, filename)
y = rawinput('[y]/n: ln -sf %s %s' % (dest, filename))
if y == 'n':
return 1
else:
return os.system('ln -sf %s %s' %(dest, filename))
else:
return -1
return link

l = linker('~', '.vimrc')
l() # line 30

执行l()时在link()第一行出错:

Traceback (most recent call last):
File "test.py", line 30, in <module>
l()
File "test.py", line 17, in link
if os.path.isfile(filename):
UnboundLocalError: local variable 'filename' referenced before assignment

它们看起来和我一样,所以我不明白为什么第二个不起作用。有什么想法吗?

最佳答案

如果您将 filename = 更改为不是filename 你不会得到一个 local variable 'filename' referenced before assignment 错误。

一旦你设置了 filename = 你就不再指代传入的参数 filename 你指的是本地的 filename您尝试在 if before 定义它时使用的内部函数的范围。

如果您将这两行和其他变量更改为类似以下内容,您将遇到与 dest 相同的问题:

filename_ = os.path.join(os.getcwd(), filename)
dest_ = os.path.join(dest, filename)

您会看到代码运行良好,因为文件名现在引用参数而不是内部函数中定义的局部变量。

如果您尝试在您的第一个函数中重新分配 x 并尝试在定义它之前访问 x,您将看到完全相同的行为:

def makeInc(x, y):
def inc():
print y + x # will cause referenced before assignment error
x = 5 # now x is local to the inner func, the x from the outer function is overridden
return y + x
return inc

如果您打印 __closure__ 属性,您将看到发生了什么:

def makeInc(x, y):
def inc():
return y + x
return inc

inc5 = makeInc(5, 10)
inc10 = makeInc(10, 5)
print(inc5.__closure__)
(<cell at 0x7f180df67e50: int object at 0xef00f8>, <cell at 0x7f180df67fa0: int object at 0xef0080>)

现在重新分配 x:

def makeInc(x, y):
def inc():
print y + x
x= 5
return y + x
return inc

inc5 = makeInc(5, 10)
inc10 = makeInc(10, 5)
print(inc5.__closure__)
(<cell at 0x7fea11889fd8: int object at 0x291e080>,)

在内部函数中重新赋值后,不再有对x的引用。

所以基本上,您的两个原始函数之间的根本区别在于,在一个函数中,您在局部范围内重新分配变量,而在另一个函数中则不是。从上面的代码可以看出,如果您在第一个函数中做类似的事情,结果是完全一样的。

有一个不错的啧啧here在作用域 LEGB 等上。

关于python - 未绑定(bind)本地错误 : local variable referenced before assignment in python closure,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29639780/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com