摘要:咱们先给全局变量下个定义:在函数外面定义的变量,就是全局变量。它的特点是:程序里的任何函数,都能直接读取甚至修改它的值。
一、先搞懂:啥是全局变量?
咱们先给全局变量下个定义:在函数外面定义的变量,就是全局变量。它的特点是:程序里的任何函数,都能直接读取甚至修改它的值。
举个生活中的例子:全局变量就像公司前台的公用打印机,不管是老板、员工还是实习生,谁都能上去用。而局部变量则像是你自己办公桌上的私人打印机,只有你能直接用。
看段代码感受下:
# 这是全局变量company = "字节跳动"def print_company:# 函数内部可以直接使用全局变量print(company)def change_company(new_name):# 声明要修改全局变量global companycompany = new_nameprint_company # 输出:字节跳动change_company("抖音集团")print_company # 输出:抖音集团这段代码里,company就是全局变量,两个函数都能操作它。看起来是不是挺方便?但方便的背后,藏着不少坑。
二、全局变量的坑1. 代码像一团乱麻,根本理不清
想象一下:如果你的程序有 1000 行代码,里面有 20 个函数,全都在修改同一个全局变量。某天这个变量出了问题,你能快速找到是哪个函数改坏的吗?
就像公司的公用打印机突然卡纸了,前台说不是她用的,实习生说没碰过,老板说自己只打印了一页 —— 你根本不知道问题出在哪。
实例场景:
现在你能一眼算出最终分数吗?如果中间再穿插 10 个类似的函数,你还能理清吗?
2. 改一处代码,到处出问题
全局变量最可怕的地方是 "牵一发而动全身"。你以为只是改了一个函数里的全局变量用法,结果其他十几个函数都因为这个改动报错了。
这就像你把公司打印机换成了新型号,结果发现财务的报销系统、人事的打卡系统、业务的报表系统都连接不上了 —— 因为它们都依赖旧打印机的接口。
实例场景:
tax_rate = 0.05 # 全局变量:税率def calculate_tax(money):return money * tax_ratedef calculate_salary(basic):return basic * (1 - tax_rate)# 某天税率调整tax_rate = 0.06# 结果所有用到税率的计算都变了print(calculate_tax(1000)) # 本来该50,现在变成60print(calculate_salary(5000)) # 工资计算也跟着变了本来只想调整税务计算,结果连工资计算也受影响了。如果这是真实的财务系统,后果不堪设想。
3. 函数变得 "不单纯",复用性为 0
好的函数应该像乐高积木 —— 拿过来就能用,不需要依赖其他零件。但如果函数里用了全局变量,它就成了 "定制积木",只能在特定场景用。
比如你写了个计算年终奖的函数,里面用了全局变量company_profit(公司利润)。当你想把这个函数用到另一个项目时,发现还得先定义company_profit才行,不然就报错。
4. 并发操作时,数据根本不靠谱
如果你的程序需要多任务并行(比如用多线程),全局变量简直是灾难。多个任务同时修改一个全局变量,最后得到的结果可能完全是错的。
就像两个人同时往一个银行账户转钱,本来应该增加 200 元,结果可能只增加了 100 元 —— 因为两个操作 "撞车" 了。
三、全局变量 vs 局部变量
为了让大家更清晰地对比,做了个表格:
特性
全局变量
局部变量
作用范围
整个程序
只在定义它的函数内部
可修改性
任何函数都能改
只有本函数能改
调试难度
高(不知道谁改的)
低(只在函数内部找问题)
代码耦合度
高(函数之间相互依赖)
低(函数独立)
复用性
内存占用
程序运行期间一直存在
函数结束后自动释放
四、实在要用全局变量?这样做更安全
当然,不是说全局变量一定不能用。在一些简单的程序里,合理使用全局变量能让代码更简洁。但如果要用,记住这 3 个原则:
1. 用大写字母命名,明确标识
约定俗成的做法是:全局变量用全大写字母 + 下划线命名,比如MAX_SIZE、DEFAULT_VALUE,让任何人看到就知道这是全局变量。
# 一眼就知道是全局变量MAX_RETRY = 3DEFAULT_TIMEOUT = 102. 尽量只读取,不修改能只读取全局变量就别修改它。如果必须修改,一定要在函数开头用global声明,并且在注释里写清楚为什么要修改。
COUNT = 0def add_count:# 因为需要统计总调用次数,所以修改全局变量global COUNTCOUNT += 13. 复杂程序用类替代如果你的程序比较复杂,需要多个函数共享一些数据,建议用类(class)来替代全局变量。类里的属性可以被多个方法共享,又比全局变量更安全可控。
# 用类替代全局变量class ScoreManager:def __init__(self):self.score = 0 # 类属性替代全局变量def add_score1(self):self.score += 10def add_score2(self):self.score += 20# 使用时创建实例manager = ScoreManagermanager.add_score1print(manager.score) # 清晰可控五、正确的变量使用习惯最后给新手朋友总结几个实用习惯,帮你远离全局变量的坑:
能局部,不全局:函数需要的数据,尽量通过参数传进去(def func(参数)),处理结果通过return返回。小范围优先:变量的作用范围越小越好,比如在if语句里定义的变量,就别拿到外面去。模块化思维:把相关的变量和函数放在一起(比如用类),形成一个独立的模块。定期自查:写完代码后,检查一下有没有没必要的全局变量,试着改成局部变量或类属性。举个正确示范:
# 不好的写法(用全局变量)result = 0def calculate(a, b):global resultresult = a * 2 + bcalculate(3, 4)print(result)# 好的写法(用局部变量+返回值)def calculate(a, b):return a * 2 + bresult = calculate(3, 4)print(result)后者的好处是:calculate函数完全独立,拿到任何程序里都能直接用,而且你能清晰地看到result的值来自哪里。
来源:凌阳教育