【自记】Python 局部变量、全局变量及global的示例
在 Python 中,全局变量能否在函数里直接使用,取决于你是 “读取” 还是 “修改”它 —— 这是理解这个问题的关键!
核心规则:
- 仅读取全局变量:函数内可以直接使用,无需
global
声明。 - 修改全局变量:必须用
global
声明,否则 Python 会把该变量视为 “局部变量”,导致报错。
先看错误代码
account = 5000000def show():print("ATM,请选择操作:")print("SELECT【1】")print("IN【2】")print("WITHDRAW【3】")print("EXIT【4】")print("PLEASE INPUT:")def select():print(account)def in_5000():account += 5000print(account)def withdraw_5000():account -= 5000print(account)if __name__ == "__main__":while True:show()selection = int(input())if selection == 1:select()elif selection == 2:in_5000()elif selection == 3:withdraw_5000()else:break
代码中,account
已经定义在模块最顶层(是真正的全局变量),此时的错误和之前分析的略有不同,核心问题出在 in_5000()
和 withdraw_5000()
函数修改全局变量时未加 global
声明,具体如下:
一、当前代码的错误分析
select()
函数(正常运行)def select():print(account) # 仅读取全局变量,无需 global,正确
这个函数只读取全局变量
account
,不修改它,所以不需要global
声明,调用时会正常打印余额。in_5000()
和withdraw_5000()
函数(报错)def in_5000():account += 5000 # 试图修改全局变量,但未加 globalprint(account)
这两个函数修改了全局变量(
account += 5000
本质是account = account + 5000
),属于 “修改操作”。
Python 规定:函数内修改全局变量必须用global
声明,否则会把account
视为 “局部变量”,而局部变量在赋值前被引用(account + 5000
中的account
),就会触发UnboundLocalError: local variable 'account' referenced before assignment
。
二、报错复现
当你运行代码并选择【2】(存款)或【3】(取款)时,会直接报错:
UnboundLocalError: local variable 'account' referenced before assignment
原因就是修改全局变量时未用 global
声明。
三、修复方案
account = 5000000def show():print("ATM,请选择操作:")print("SELECT【1】")print("IN【2】")print("WITHDRAW【3】")print("EXIT【4】")print("PLEASE INPUT:")def select():print(account) # 仅读取,无需globaldef in_5000():global account # 修改全局变量,必须声明account += 5000print(account)def withdraw_5000():global account # 修改全局变量,必须声明account -= 5000print(account)if __name__ == "__main__":while True:show()selection = int(input())if selection == 1:select()elif selection == 2:in_5000()elif selection == 3:withdraw_5000()else:print("结束") # 调整到break前,确保执行break
四、关键结论
- 全局变量仅读取时,函数内可以直接使用,无需
global
(如select()
函数)。 - 全局变量需要修改时(赋值、
+=
、-=
等),函数内必须用global
声明(如in_5000()
和withdraw_5000()
函数)。 - 你之前的代码错误在于 “修改全局变量时未加
global
”,而非变量定义位置,这是之前分析中未明确区分 “读取” 和 “修改” 导致的细节疏漏,特此纠正。