当我 运行 这个程序时,为什么 python 给我一个 UnboundLocalError?
Why is python giving me an UnboundLocalError when I run this program?
背景
我目前正在试验计算机学习,我做了一个函数,你输入“真”或“假”,计算机就会知道它是哪个布尔值,之后程序会打印出计算机做出的正确猜测的百分比:
import math
import random
endgame = False
def oneround():
Q1max = 1
Q1min = -2
guess = False
answer = 0
while guess == False:
useranswer = input("True or False?")
if useranswer == "True" or useranswer == "true":
answer = True
guess = True
elif useranswer == "False" or useranswer == "false":
answer = False
guess = True
corrects = 0
incorrects = 0
howmanytimes = int(input("how many times do you want the computer to guess? (If you want to end the game, type in letters instead of a number.) "))
for x in range(0,howmanytimes):
choice = random.randint(Q1min,Q1max)
if choice >= 0:
guess = True
else:
guess = False
if guess == answer:
corrects += 1
if guess == True:
Q1max += 1
else:
Q1min -= 1
else:
incorrects += 1
if guess == False:
Q1max += 1
else:
Q1min -= 1
percent = (corrects/howmanytimes)*100
print ("The computer learned to guess correctly",(str(math.floor(percent))+"%"),"of the time.")
while endgame == False:
try:
oneround()
except ValueError:
endgame = True
然后我尝试通过添加 2 个全局变量 percentavg
和 percentavgnum
来改进我的程序,这将在程序结束时对所有成功百分比进行平均:
import math
import random
endgame = False
global percentavg
global percentavgnum
percentavg = 0
percentavgnum = 0
def oneround():
Q1max = 1
Q1min = -2
guess = False
answer = 0
while guess == False:
useranswer = input("True or False?")
if useranswer == "True" or useranswer == "true":
answer = True
guess = True
elif useranswer == "False" or useranswer == "false":
answer = False
guess = True
corrects = 0
incorrects = 0
howmanytimes = int(input("how many times do you want the computer to guess? (If you want to end the game, type in letters instead of a number.) "))
for x in range(0,howmanytimes):
choice = random.randint(Q1min,Q1max)
if choice >= 0:
guess = True
else:
guess = False
if guess == answer:
corrects += 1
if guess == True:
Q1max += 1
else:
Q1min -= 1
else:
incorrects += 1
if guess == False:
Q1max += 1
else:
Q1min -= 1
percent = (corrects/howmanytimes)*100
percentavg += percent
percentavgnum += 1
print ("The computer learned to guess correctly",(str(math.floor(percent))+"%"),"of the time.")
while endgame == False:
try:
oneround()
except ValueError:
endgame = True
print ("The computer guessed correctly",(str(math.floor(percentavg/percentavgnum))+"%"),"of the time")
问题
但是每当我 运行 程序时我总是收到这个错误:
Traceback (most recent call last):
File "main.py", line 49, in <module>
oneround()
File "main.py", line 44, in oneround
percentavg += percent
UnboundLocalError: local variable 'percentavg' referenced before assignment
有谁知道我做错了什么吗?
使用global
。把它放在函数的顶部,后面是变量名。像这样:global percentavg, percentavgnum
注意:名称必须以逗号分隔。
这个问题与Python如何确定变量的范围有关。
您可以注意到当您尝试通过 percentavg += percent
.
递增 percentavg
时发生错误
所以您正在尝试分配一个新值给percentavg
。
问题是在Python中,当你给一个变量赋值时,这个变量就变成了一个local变量。但是 percentavg
还没有定义在这个范围内(oneround()
的范围,所以你得到这个 UnboundLocalError
.
所有这些都在这里详细解释:
https://docs.python.org/3/faq/programming.html#why-am-i-getting-an-unboundlocalerror-when-the-variable-has-a-value
您至少有 3 个选项:
- 定义
oneround()
中的变量:
def oneround():
percentavg = 0
percentavgnum = 0
# ...
- 将您的变量作为参数传递给
oneround()
:
percentavg = 0
percentavgnum = 0
oneround(percentavg,percentavgnum)
而且您根本不需要将变量声明为全局变量。
- 使用
global
在你的函数中访问你的外部作用域变量:
(这是@Blue提出的)
def oneround():
global percentavg
global percentavgnum
关键字global
用于访问外部范围变量(在函数范围之外声明的变量)。
如果您选择选项 1,您可以删除代码开头的这些行:
global percentavg
global percentavgnum
percentavg = 0
percentavgnum = 0
如果您选择选项 2,您可以删除代码开头的这些行:
global percentavg
global percentavgnum
但您必须保留这些行:
percentavg = 0
percentavgnum = 0
这些行可能在代码的开头,但也可能在调用 oneround()
.
之前的 while 循环或 try 语句中
但是,根据您的代码,选项 1 是最佳编码实践。
与其使用全局变量并依赖函数的副作用,不如编写函数以接受需要 更新 的模块级变量作为参数,并将 return 更新 值。
>>> def f(one,two,three):
... return one*1,two*2,three*3
...
>>> a,b,c = 'xyz'
>>> a,b,c = f(a,b,c)
>>> a
'x'
>>> b
'yy'
>>> c
'zzz'
>>>
背景
我目前正在试验计算机学习,我做了一个函数,你输入“真”或“假”,计算机就会知道它是哪个布尔值,之后程序会打印出计算机做出的正确猜测的百分比:
import math
import random
endgame = False
def oneround():
Q1max = 1
Q1min = -2
guess = False
answer = 0
while guess == False:
useranswer = input("True or False?")
if useranswer == "True" or useranswer == "true":
answer = True
guess = True
elif useranswer == "False" or useranswer == "false":
answer = False
guess = True
corrects = 0
incorrects = 0
howmanytimes = int(input("how many times do you want the computer to guess? (If you want to end the game, type in letters instead of a number.) "))
for x in range(0,howmanytimes):
choice = random.randint(Q1min,Q1max)
if choice >= 0:
guess = True
else:
guess = False
if guess == answer:
corrects += 1
if guess == True:
Q1max += 1
else:
Q1min -= 1
else:
incorrects += 1
if guess == False:
Q1max += 1
else:
Q1min -= 1
percent = (corrects/howmanytimes)*100
print ("The computer learned to guess correctly",(str(math.floor(percent))+"%"),"of the time.")
while endgame == False:
try:
oneround()
except ValueError:
endgame = True
然后我尝试通过添加 2 个全局变量 percentavg
和 percentavgnum
来改进我的程序,这将在程序结束时对所有成功百分比进行平均:
import math
import random
endgame = False
global percentavg
global percentavgnum
percentavg = 0
percentavgnum = 0
def oneround():
Q1max = 1
Q1min = -2
guess = False
answer = 0
while guess == False:
useranswer = input("True or False?")
if useranswer == "True" or useranswer == "true":
answer = True
guess = True
elif useranswer == "False" or useranswer == "false":
answer = False
guess = True
corrects = 0
incorrects = 0
howmanytimes = int(input("how many times do you want the computer to guess? (If you want to end the game, type in letters instead of a number.) "))
for x in range(0,howmanytimes):
choice = random.randint(Q1min,Q1max)
if choice >= 0:
guess = True
else:
guess = False
if guess == answer:
corrects += 1
if guess == True:
Q1max += 1
else:
Q1min -= 1
else:
incorrects += 1
if guess == False:
Q1max += 1
else:
Q1min -= 1
percent = (corrects/howmanytimes)*100
percentavg += percent
percentavgnum += 1
print ("The computer learned to guess correctly",(str(math.floor(percent))+"%"),"of the time.")
while endgame == False:
try:
oneround()
except ValueError:
endgame = True
print ("The computer guessed correctly",(str(math.floor(percentavg/percentavgnum))+"%"),"of the time")
问题
但是每当我 运行 程序时我总是收到这个错误:
Traceback (most recent call last):
File "main.py", line 49, in <module>
oneround()
File "main.py", line 44, in oneround
percentavg += percent
UnboundLocalError: local variable 'percentavg' referenced before assignment
有谁知道我做错了什么吗?
使用global
。把它放在函数的顶部,后面是变量名。像这样:global percentavg, percentavgnum
注意:名称必须以逗号分隔。
这个问题与Python如何确定变量的范围有关。
您可以注意到当您尝试通过 percentavg += percent
.
percentavg
时发生错误
所以您正在尝试分配一个新值给percentavg
。
问题是在Python中,当你给一个变量赋值时,这个变量就变成了一个local变量。但是 percentavg
还没有定义在这个范围内(oneround()
的范围,所以你得到这个 UnboundLocalError
.
所有这些都在这里详细解释: https://docs.python.org/3/faq/programming.html#why-am-i-getting-an-unboundlocalerror-when-the-variable-has-a-value
您至少有 3 个选项:
- 定义
oneround()
中的变量:
def oneround():
percentavg = 0
percentavgnum = 0
# ...
- 将您的变量作为参数传递给
oneround()
:
percentavg = 0
percentavgnum = 0
oneround(percentavg,percentavgnum)
而且您根本不需要将变量声明为全局变量。
- 使用
global
在你的函数中访问你的外部作用域变量:
(这是@Blue提出的)
def oneround():
global percentavg
global percentavgnum
关键字global
用于访问外部范围变量(在函数范围之外声明的变量)。
如果您选择选项 1,您可以删除代码开头的这些行:
global percentavg
global percentavgnum
percentavg = 0
percentavgnum = 0
如果您选择选项 2,您可以删除代码开头的这些行:
global percentavg
global percentavgnum
但您必须保留这些行:
percentavg = 0
percentavgnum = 0
这些行可能在代码的开头,但也可能在调用 oneround()
.
但是,根据您的代码,选项 1 是最佳编码实践。
与其使用全局变量并依赖函数的副作用,不如编写函数以接受需要 更新 的模块级变量作为参数,并将 return 更新 值。
>>> def f(one,two,three):
... return one*1,two*2,three*3
...
>>> a,b,c = 'xyz'
>>> a,b,c = f(a,b,c)
>>> a
'x'
>>> b
'yy'
>>> c
'zzz'
>>>