python-使用列表切片而不是pop()会导致UnboundLocalError

python-使用列表切片而不是pop()会导致UnboundLocalError,python,list,scope,Python,List,Scope,当我使用while len(my_list)>5:my_list.pop()截断列表中的条目时,我没有遇到任何错误。但是,当我使用my_list=my_list[:5]试图达到相同的目的时,我在代码的前面部分中看到一个UnboundLocalError,在切片发生之前 我会尽量只发布相关的部分。首先,脚本首先要做的一件事是从一个pickle文件加载列表-如果失败,它将被分配一个默认值。除非我的理解很差,否则这个列表只存在于脚本的全局名称空间中 try: #either load hi-sc

当我使用
while len(my_list)>5:my_list.pop()
截断列表中的条目时,我没有遇到任何错误。但是,当我使用
my_list=my_list[:5]
试图达到相同的目的时,我在代码的前面部分中看到一个UnboundLocalError,在切片发生之前

我会尽量只发布相关的部分。首先,脚本首先要做的一件事是从一个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
然后我得到以下结果:

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
我看到了
回溯(最近一次呼叫最后一次):
文件“sf.py”,第1029行,在
游戏。主循环()
主循环中第909行的文件“sf.py”
self.game\u over\u loop()
文件“sf.py”,第844行,在游戏循环中
如果ship.score>scoreList[-1][1]:#如果ship.score足够高,则获得_player_分数
UnboundLocalError:分配前引用的局部变量“scoreList”
那么这是怎么发生的呢


更新:我很感激有人建议将它声明为一个全局变量,但我的问题不是“如何解决这个问题”,而是“为什么这是list[:index]的一个问题,而不是在使用list.pop()时。”

首先定义了
scoreList
在哪里?它是该函数中的一个局部变量吗?问题可能是执行
scoreList=…
会导致它与本地范围绑定。在这种情况下,请尝试将
全局计分表置于函数顶部。

尝试以下操作:

def game_over_loop(self):
    global scoreList
    if ship.score > scoreList[-1][1]:
        #rest of my code

对函数中出现的变量的任何赋值(不计算该函数中嵌套的函数或类中的赋值)都会导致Python创建该名称的局部变量。然后,对函数内变量的所有访问都将尝试访问局部变量,而不是全局变量。因此,

scoreList = scoreList[:5]
使函数内对
scoreList
的所有访问尝试访问从未初始化的
scoreList
本地

当你这样做的时候

scoreList.pop()

函数中的
scoreList
变量没有赋值。(对象
scoreList
指的是更改状态,但这不是对变量的赋值。)因此,Python将对
scoreList
的访问解释为寻找全局变量,这正是您想要的。

为什么不将scoreList作为类的属性呢?当然,我可以做到这一点——这段代码是我正在重构的老项目的一种方式,所以可能会发生这样的事情。我相信这会解决这个问题,但它并没有回答我的好奇:/
scoreList
在该函数中不是全局变量,局部变量是在解析函数体时确定的。当Python看到像这样的赋值语句:
scoreList=…
时,它会将
scoreList
设置为局部变量。还要通过:@undefinedisnotafunction-即使它在方法中的
globals()
scoreList.pop()