Python &引用;赋值前引用的局部变量“;
我来自一个拥有丰富Java和PHP经验的国家,因此当涉及到Python时,很多规则对我来说都没有意义 我在下面有一个递归斐波那契函数,它指出了错误:Python &引用;赋值前引用的局部变量“;,python,function,recursion,global-variables,Python,Function,Recursion,Global Variables,我来自一个拥有丰富Java和PHP经验的国家,因此当涉及到Python时,很多规则对我来说都没有意义 我在下面有一个递归斐波那契函数,它指出了错误: Traceback (most recent call last): File "C:\Users\Nic\workspace\lab8\src\Main.py", line 26, in <module> print fibcount(27),"took",calls,"calls." File "C:\Users\N
Traceback (most recent call last):
File "C:\Users\Nic\workspace\lab8\src\Main.py", line 26, in <module>
print fibcount(27),"took",calls,"calls."
File "C:\Users\Nic\workspace\lab8\src\Main.py", line 19, in fibcount
calls += 1
UnboundLocalError: local variable 'calls' referenced before assignment
回溯(最近一次呼叫最后一次):
文件“C:\Users\Nic\workspace\lab8\src\Main.py”,第26行,在
打印fibcount(27),“take”,calls,calls
文件“C:\Users\Nic\workspace\lab8\src\Main.py”,第19行,在fibcount中
调用+=1
UnboundLocalError:赋值前引用的局部变量“calls”
这是我的代码:
calls = 0
def fibcount(n):
calls += 1
if n < 2:
return (1,1)
f1,c1 = fibcount(n-1)
f2,c2 = fibcount(n-2)
return (f1+f2,c1+c2+1)
print fibcount(27),"took",calls,"calls."
calls=0
def光纤计数(n):
调用+=1
如果n<2:
返回(1,1)
f1,c1=纤维计数(n-1)
f2,c2=纤维计数(n-2)
返回(f1+f2、c1+c2+1)
打印fibcount(27),“take”,calls,calls
在Java中,这显然是可行的,因为调用是函数fibcount()
的一个全局变量,所以调用不在作用域中让我感到困惑
我做错了什么?在Python中,您需要将全局变量声明为函数中的全局变量,函数会将它们重新分配给不同的值。您将为此使用:
def fibcount(n):
global calls
...
否则,Python将把调用
变量视为本地变量
但是请注意,您只需要对重新分配的全局变量执行此操作。简单地阅读他们的价值观就可以了
同样,在Python中,像这样重新分配全局变量被认为是丑陋的,应该尽可能避免。大多数时候,您应该坚持将值传递给函数,然后将变量重新分配给它们的返回值。如果需要维护状态,请使用类
Python中保证全局变量的唯一时间是当您需要模块级常量时。在这种情况下,公约规定他们应该有所有CAP名称:
MYCONST = 12345
在Python中,需要将全局变量声明为函数中的全局变量,函数会将它们重新分配给不同的值。您将为此使用:
def fibcount(n):
global calls
...
否则,Python将把调用
变量视为本地变量
但是请注意,您只需要对重新分配的全局变量执行此操作。简单地阅读他们的价值观就可以了
同样,在Python中,像这样重新分配全局变量被认为是丑陋的,应该尽可能避免。大多数时候,您应该坚持将值传递给函数,然后将变量重新分配给它们的返回值。如果需要维护状态,请使用类
Python中保证全局变量的唯一时间是当您需要模块级常量时。在这种情况下,公约规定他们应该有所有CAP名称:
MYCONST = 12345
我认为最好明确指出,当您仅读取值时,不需要使用
global
关键字。然而,我认为我们需要小心“修改”这个词,因为来自许多其他语言的人在重新绑定和变异之间没有很强的心理区别(并且会考虑这两件事都是“修改”)。如果我们要重新绑定(又称重新分配)名称,我们只需要global
。我们可以自由地改变全局对象(例如,如果调用
是一个列表,我们可以在不使用全局
关键字的情况下追加或删除其元素)。我试图避免讨论“Python没有变量,它有名称”,因为这可能会混淆OP。这里的重要部分是使用global
关键字。关于原因的确切细节超出了我的回答范围。:)我很感激不想打开那罐虫子!为此,我认为,在前面尽可能使用精确的术语,这将使can有最好的机会保持关闭状态。我理解有时候你不能向某人解释某件事,除非他们有更多的理解,否则你不能随意使用术语,但在这种情况下,重新分配是一个很好的选择:它可以提高精度而不增加冗长性。我认为最好明确指出,当您仅读取值时,不需要使用global
关键字。然而,我认为我们需要小心“修改”这个词,因为来自许多其他语言的人在重新绑定和变异之间没有很强的心理区别(并且会考虑这两件事都是“修改”)。如果我们要重新绑定(又称重新分配)名称,我们只需要global
。我们可以自由地改变全局对象(例如,如果调用
是一个列表,我们可以在不使用全局
关键字的情况下追加或删除其元素)。我试图避免讨论“Python没有变量,它有名称”,因为这可能会混淆OP。这里的重要部分是使用global
关键字。关于原因的确切细节超出了我的回答范围。:)我很感激不想打开那罐虫子!为此,我认为,在前面尽可能使用精确的术语,这将使can有最好的机会保持关闭状态。我明白,有时候你不能在没有人理解之前随意使用术语向他们解释某件事,但在这种情况下,重新分配是一个不错的选择:它可以在不增加冗长的情况下提高精确度。