当我使用while len(my_list) > 5: my_list.pop()
截断列表中的条目时,我没有遇到任何错误。但是,当我使用my_list = my_list[:5]
尝试实现相同目的时,我会在之前部分的代码中看到UnboundLocalError,在切片发生之前。< / p>
我会尝试只发布看似相关的部分。首先,脚本所做的第一件事就是从pickle文件中加载列表 - 如果失败则会为其分配一个默认值。除非我的理解很差,否则此列表只存在于脚本的全局命名空间中。
try: #either load hi-score list, or create a default list
with open('scores.py', 'r') as f:
scoreList = pickle.loads(f.read())
except:
scoreList = [
['NME', 15000],
['HAS', 12000],
['LDS', 10000],
['AKT', 8000],
['JAS', 5000]
]
然后检查列表以查看是否应该输入新条目;如果是,则收集玩家姓名缩写。否则游戏只会显示分数。
def game_over_loop(self):
##other unrelated code that only runs one time
if ship.score > scoreList[-1][1]:
go_state = 'get_player_score'
###...
while displayScores:
###...
if len(playerInitials.text) >= 3:
scoreList.append([playerInitials.text, ship.score])
scoreList.sort(key=lambda x: x[1])
scoreList.reverse()
###here's the problem###
scoreList = scoreList[:5] #bad
#while len(scoreList) > 5: #good
# scoreList.pop()
########################
pickleScore = pickle.dumps(scoreList)
with open('scores.py', 'w') as f:
f.write(pickleScore)
go_state = 'build_scores'
如果我使用注释之间的语法,我会收到以下错误:
Traceback (most recent call last):
File "sf.py", line 1024, in <module>
TheGame.master_loop()
File "sf.py", line 904, in master_loop
self.game_over_loop()
File "sf.py", line 841, in game_over_loop
if ship.score > scoreList[-1][1]: #if ship.score high enough, get_player_score
UnboundLocalError: local variable 'scoreList' referenced before assignment
但是,如果我只是在列表len
大于5和pop()
条目时进行迭代,则没有问题。
我不清楚在注释代码之前如何发生UnboundLocalError 。由于scoreList
是全局的(对吗?),看起来最糟糕的事情就是排序后的本地实例,并且追加将是唯一一个被切片然后腌制的实例,但它并没有#39} ;甚至在抛出错误之前在脚本中得到那么远。
事实上,如果我将这些行添加到脚本中:
if 'scoreList' in globals():
print "I see it"
然后我得到以下内容:
I see it
Traceback (most recent call last):
File "sf.py", line 1029, in <module>
TheGame.master_loop()
File "sf.py", line 909, in master_loop
self.game_over_loop()
File "sf.py", line 844, in game_over_loop
if ship.score > scoreList[-1][1]: #if ship.score high enough, get_player_score
UnboundLocalError: local variable 'scoreList' referenced before assignment
那么这是怎么发生的?
更新:我很欣赏将其声明为全局变量的建议,但我的问题是“我该怎样解决这个问题”#34;和#34;为什么这是列表[:index]的事情,但在使用list.pop()&#34;时却没有。
答案 0 :(得分:1)
首先定义scoreList
的位置 - 它是该函数中的本地吗?问题可能是执行scoreList = ...
会导致它与本地范围绑定。在这种情况下,请尝试将global scoreList
放在函数的顶部。
答案 1 :(得分:1)
对函数中出现的变量的任何赋值(不计算嵌套在该函数中的函数或类中的赋值)会导致Python创建该名称的局部变量。然后,对函数内部变量的所有访问都将尝试访问局部变量,而不是全局变量。因此,
scoreList = scoreList[:5]
导致对函数内scoreList
的所有访问尝试访问从未初始化的scoreList
本地。
当你这样做时
scoreList.pop()
函数中的scoreList
变量没有赋值。 (对象scoreList
指的是更改状态,但这不是对变量的赋值。)因此,Python将对scoreList
的访问解释为寻找全局变量,这就是你想要的
答案 2 :(得分:0)
试试这个:
def game_over_loop(self):
global scoreList
if ship.score > scoreList[-1][1]:
#rest of my code