pis*_*bee 2 python scope global-scope python-3.x spyder
这是一个寻找正整数aandb和 的最大公约数的例子a <= b。我从较小的a和一个一个的减号开始,检查它是否是两个数字的除数。
def gcdFinder(a, b):
testerNum = a
def tester(a, b):
if b % testerNum == 0 and a % testerNum == 0:
return testerNum
else:
testerNum -= 1
tester(a, b)
return tester(a, b)
print(gcdFinder(9, 15))
Run Code Online (Sandbox Code Playgroud)
然后,我收到错误消息,
UnboundLocalError: local variable 'testerNum' referenced before assignment.
使用后global testerNum,它成功地3在Spyder控制台中显示了答案......
但是在 pythontutor.com 中,它说NameError: name 'testerNum' is not defined(链接)。
Q1:在 Spyder 中,我认为这global testerNum是一个问题,因为testerNum = a它不在全局范围内。它在 function 的范围内gcdFinder。这个描述正确吗?如果是这样,Spyder 是如何给出答案的?
Q2:在pythontutor中,说最后一个截图,pythontutor中的NameError问题如何解决?
Q3:为什么Spyder和pythontutor的结果有差异,哪个是正确的?
Q4:最好不要使用global方法吗?
——
更新:Spyder 问题是由于上次运行存储的值造成的,因此它9已经定义为。这使得global testerNum工作。我已经删除了 Q1 和 Q3。
问题:
在尝试解析变量引用时,Python 首先检查本地范围,然后检查任何封闭函数的本地范围。例如这段代码:
def foo():
x=23
def bar():
return x +1
return bar
print(foo()())
Run Code Online (Sandbox Code Playgroud)
将运行并打印出来,24因为 when 在 中x被引用bar,因为x在本地范围内没有它在封闭函数 ( foo)的范围内找到它。但是,一旦您尝试分配给变量,Python 就会假定它是在本地作用域中定义的。所以这:
def foo():
x=23
def bar():
x = x + 1
return x
return bar
print(foo()())
Run Code Online (Sandbox Code Playgroud)
会抛出一个UnboundLocalError因为我试图分配给x它意味着它将在本地范围内查找,但我试图分配给它的值是基于x来自封闭范围的。由于分配将搜索限制为x本地范围,因此无法找到它并且我收到错误消息。
因此,由于testerNum -= 1else 子句中的这一行,您的错误出现了,它将搜索限制testerNum在它不存在的本地范围内。
修复:
该global声明是不正确的,因为,正如你指出,testerNum没有在全球范围内定义。我对 Spyder 不熟悉,也不知道它为什么在那里工作,但它似乎以某种方式testerNum在其全局范围内获得了一个变量。
如果您使用的是 Python3,您可以通过更改您的global testerNum行来解决此问题,该行nonlocal testerNum只是告诉 Python 尽管已分配给 testerNum 并没有在本地范围内定义并继续向外搜索。
def foo():
x=23
def bar():
nonlocal x
x = x + 1
return x
return bar
>>> print(foo()())
24
Run Code Online (Sandbox Code Playgroud)
另一个适用于 Python 2 或 3 的选项是testerNum按照 Brambor 在他们的回答中概述的方式传递。
| 归档时间: |
|
| 查看次数: |
530 次 |
| 最近记录: |