Python变量作用域:函数内修改全局变量score、count报错原因及解法
报错原因
Python作用域遵循LEGB查找规则,核心逻辑是:
- 对于函数内仅做读取操作的变量,Python会逐层从局部、外层函数、全局、内置作用域查找对应变量
- 只要在函数内对某个变量执行赋值操作(包括
+=/-=这类增量赋值,本质属于赋值),Python就会默认该变量是当前函数的局部变量,不会主动向外层作用域查找
你的代码中score和count定义在全局作用域,但在main()函数内直接执行count += 1、score += 1这类赋值操作时,Python会将二者判定为main()的局部变量。但你并没有在函数内部给这两个局部变量做初始化,直接执行增量运算就会触发UnboundLocalError,提示局部变量在赋值前被引用。
另外你的代码存在一处冗余写法:把main()函数定义写在while循环内部,每次循环都会重复定义一次函数,完全可以把函数定义移到循环外层,减少不必要的性能开销。
简单解决方法
最直接的修复方式是在main()函数内部操作score和count之前,用global关键字声明这两个变量来自全局作用域,告诉Python不要将其判定为局部变量。修复后的可运行代码如下:
import random capitals = ["New Dehli","Washington DC", "Tokyo", "London", "Lisbon", "Madrid", "Paris", "Berlin", "Warsaw", "Kiev", "Moscow", "Prague", "Rome"] countries = ["India", "USA" ,"Japan" ,"England","Portugal", "Spain", "France", "Germany", "Poland", "Ukraine", "Russia", "Czech Republic", "Italy"] score, count = 0, 0 # 函数定义移到循环外,避免重复定义 def main(): # 声明使用全局作用域的score和count global score, count index = random.randrange(0, 13) guess = input(f"What is the capital of {countries[index]} ?: ").lower() count += 1 if guess == capitals[index].lower(): print("You guessed correct!") score += 1 else: print(f"Incorrect, correct answer is {capitals[index]}.") play = input('Would you like to play? Yes or No: ').lower() while play == 'yes': main() play = input('Would you like to play again? Yes or No: ').lower() # 修正原代码输出语句的小笔误:Your -> You print(f"You guessed {score} correctly out of {count}!")
如果要写更规范的代码,不建议滥用全局变量,可以把score和count作为参数传入函数,运算后将结果返回再更新全局值,但对于这个小型脚本来说,使用global关键字是成本最低、最简便的修复方案。
内容的提问来源于stack exchange,提问作者Hissan
相关产品推荐
相关产品推荐

