以下是查找正整数a
和b
以及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))
然后,我收到了错误消息,
UnboundLocalError: local variable 'testerNum' referenced before assignment
。
使用global testerNum
后,它在Spyder控制台中成功显示了答案3
...
但是在pythontutor.com中,它说NameError: name 'testerNum' is not defined
(link)。
Q1:在Spyder中,我认为 global testerNum
是一个问题,因为testerNum = a
不在全球范围内。它在函数gcdFinder
的范围内。这种描述是否正确?如果是这样,Spyder是如何显示答案的?
Q2:在pythontutor中,说最后的截图,如何解决pythontutor中的NameError问题?
Q3:为什么Spyder和pythontutor的结果有差异,哪个是正确的?
问题4:最好不要使用global
方法吗?
-
更新:Spyder问题是由于之前运行时存储的值,因此它已经定义为9
。这使global testerNum
工作。我删除了Q1&amp; Q3。
答案 0 :(得分:4)
问题:
在尝试解析变量引用时,Python首先检查本地作用域,然后检查任何封闭函数的本地作用域。例如这段代码:
def foo():
x=23
def bar():
return x +1
return bar
print(foo()())
将运行并打印24
,因为x
内引用了bar
,因为本地范围内没有x
,它会在foo
范围内找到它封闭函数(def foo():
x=23
def bar():
x = x + 1
return x
return bar
print(foo()())
)。但是,只要您尝试分配给变量,Python就会假定它是在本地范围内定义的。所以这个:
UnboundLocalError
将抛出x
,因为我试图分配给x
,这意味着它将在本地范围内被查找,但我试图分配给它的值是基于的来自封闭范围的x
。由于分配将testerNum -= 1
的搜索范围限制为本地范围,因此无法找到它并且我收到错误。
因此,由于您的else子句中的testerNum
行,您的错误即将出现,它将global
的搜索限制在不存在的本地范围内。
修复:
testerNum
声明不正确,因为正如您所指出的那样,testerNum
未在全局范围内定义。我不熟悉Spyder并且不知道为什么它在那里工作但似乎它在某种程度上在其全局范围内得到了global testerNum
变量。
如果您正在使用Python3,可以通过将nonlocal testerNum
行更改为def foo():
x=23
def bar():
nonlocal x
x = x + 1
return x
return bar
>>> print(foo()())
24
来解决这个问题,而testerNum
只告诉Python,尽管已经分配了,但却没有在本地范围内定义testerNum,继续向外搜索。
npm install rxjs
在Python 2或3中可以使用的另一个选项是传递server.ts
作为Brambor在答案中概述的内容。
答案 1 :(得分:2)
回答 Q2 和 Q4 。
正如我在评论中所写,您可以将testerNum解析为参数。
您的代码将如下所示:
def gcdFinder(a, b):
testerNum = a
def tester(a, b, testerNum):
if b % testerNum == 0 and a % testerNum == 0:
return testerNum
else:
testerNum -= 1
return tester(a, b, testerNum) # you have to return this in order for the code to work
return tester(a, b, testerNum)
print(gcdFinder(9, 15))
编辑:(见注释)
答案 2 :(得分:0)
仅针对问题4,是的,最好不要使用global
。 global
通常会突出代码设计不佳。
你会遇到很多麻烦;我强烈建议您查找计算GCD的标准方法,并改为实现Euclid算法。编码细节留给学生练习。