一文搞懂Python局部变量与全局变量的12大陷阱

今天我们要来聊聊一个让人又爱又恨的话题——局部变量与全局变量的八大迷雾。在Python的世界里,变量就像是你的小宠物,有时候它们乖乖听话,但一不小心就给你挖了个大坑!别担心,今天我们就一起把这些陷阱挖出来,填平它,让你的编程之路畅通无阻!

1. 基础篇:什么是局部和全局变量?

想象你在厨房做饭,ingredient(食材)是全局的,因为整个厨房都能用到它。而当你在切洋葱时,那把刀(knife)就是局部的,只在这个特定任务(函数)里使用。

ingredient = "洋葱"def chop():knife = "锋利的菜刀"print(f"用{knife}{ingredient}")chop()

这里,knife仅在chop函数内部可见,就是局部变量,而ingredient是全局变量,哪里都能访问。

2. 修改全局变量的第一坑:你以为你能改?

直接在函数里修改全局变量?Python可不轻易让你得逞!

global_var = 10def change_global():global_var = 20 # 注意,这只是创建了一个新的局部变量!change_global()
print(global_var) # 猜猜看,输出是多少?

输出还是10!Python说:“嘿,你这是新建了个局部的global_var,原来的我可没动哦。”

3. 正确修改全局变量:要用global关键字!

想动我的全局变量?得先打招呼!

global_var = 10def change_global_correctly():global global_varglobal_var = 20change_global_correctly()
print(global_var) # 这次对了吧?

这次,输出是20,因为我们明确告诉Python:“嘿,我要动的是全局的那个家伙。”

4. 局部变量的“幽灵”效应

当你在函数内未声明就使用变量名,Python会认为你在找全局变量,但这可能会引发一些诡异的现象。

def mystery():print(unknown_var) # 啊哦,这是谁?try:mystery()
except NameError as e:print(e) # 未知变量错误,它真的存在吗?

这会抛出NameError,提醒你“unknown_var”这个幽灵并不存在于全局空间。

5. 非直观的变量作用域:嵌套函数

嵌套函数可以访问外层函数的变量,但修改时要小心!

def outer():outer_var = "外层的宝藏"def inner():print(outer_var) # 能找到我外公的宝藏吗?outer_var = "被内层修改了" # 实际上,这创造了一个新的局部变量inner()print(outer_var) # 外层的值会变吗?outer() # 来看看结果

你会发现,外层的值没变,因为内层创建了一个同名的局部变量。

6. 使用nonlocal关键字的场景

当你确实想在嵌套函数中修改外层函数的变量时,nonlocal来帮忙!

def outer():outer_var = "原始宝藏"def inner():nonlocal outer_varouter_var = "宝藏升级了"print(outer_var)inner()print(outer_var) # 这次会怎样?outer() # 哈哈,成功修改!

nonlocal关键字让Python知道你想修改的是外层的变量,不是创建新的。

7. 全局变量的滥用:是福还是祸?

全局变量用得爽,但过度依赖就像吃太多糖,短期内甜,长期有害。它可能导致代码难以维护和测试。尽量通过函数参数和返回值传递数据,保持模块间的独立性,这样你的代码才会更健康!

8. 小心闭包的陷阱

闭包是Python中的高级特性,但也可能因变量作用域而让人困惑。

def create_counter():count = 0def counter():nonlocal countcount += 1return countreturn countermy_counter = create_counter()
print(my_counter()) # 1
print(my_counter()) # 2
# 看,count被正确地保留和增加了!

闭包可以记住外部函数的状态,但记得,这也意味着它可能会保留比预期更多的内存,所以使用时要谨慎。


高级技巧

9. 利用模块级别的变量

在大型项目中,有时需要在整个模块范围内共享数据。你可以定义模块级别的变量来实现这一目的。但请记住,这样做可能会增加模块间的耦合度,要谨慎使用。

# my_module.py
shared_data = []def add_to_shared(data):shared_data.append(data)def get_shared():return shared_data# 另一个文件中使用
import my_modulemy_module.add_to_shared("Hello")
print(my_module.get_shared()) # 输出: ['Hello']

10. 全局变量的替代方案:配置文件与环境变量

在处理配置信息或应用设置时,使用配置文件(如.ini, .json, 或环境变量)是一个更好的选择,而不是硬编码全局变量。这样可以提高代码的灵活性和可维护性。

# 假设有一个config.json
{"database": "my_db","port": 5432
}import json
import os# 读取配置文件
with open('config.json') as f:config = json.load(f)# 或者使用环境变量
DB_NAME = os.getenv('DB_NAME', 'default_db') # 如果环境变量不存在,则使用'default_db'

11. 上下文管理器与with语句

虽然这不是直接关于变量作用域的,但了解上下文管理器可以帮助你更好地管理资源,比如文件操作时的自动关闭。

with open('myfile.txt', 'w') as file:file.write("Hello, world!")
# 文件在这里自动关闭,无需显式调用file.close()

这里的file变量在with块内有效,一旦执行完毕,Python会确保资源得到释放。

12. 闭包的高级应用:记忆化

记忆化是一种优化技术,用于存储函数计算的中间结果,减少重复计算。这对于有重叠子问题的递归函数尤其有用。

def memoize(func):cache = {}def wrapper(*args):if args not in cache:cache[args] = func(*args)return cache[args]return wrapper@memoize
def fibonacci(n):if n <= 1:return nelse:return fibonacci(n-1) + fibonacci(n-2)print(fibonacci(10)) # 55,而且只计算了一次n=1到n=10

通过这种方式,memoize装饰器创建了一个闭包,它记录了函数调用的结果,避免了重复劳动。


这些额外的知识点和技巧,希望能为你的Python学习之旅增添更多色彩。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/859731.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于VTK9.3.0+Visual Studio2017 c++实现DICOM影像MPR多平面重建+V R体绘制4个视图展示功能的实现

开源库&#xff1a;VTK9.3.0 开发工具&#xff1a;Visual Studio2017 开发语言&#xff1a;C 实现过程&#xff1a; class vtkImageInteractionCallback : public vtkCommand { public:static vtkImageInteractionCallback* New(){return new vtkImageInteractionCallback()…

文库小程序搭建部署:实现资源共享正向反馈

文档库相信大家应该不陌生&#xff0c;日常我们的工作模板、会议模板、求职时的简历模板、教育界的教学模板等来源方式都出自于文档库&#xff0c;随着互联网的发展和工作需求&#xff0c;文档模板开启了新型的知识变现新途径&#xff0c;通过文库小程序&#xff0c;我们不仅能…

Web服务器与Apache(LAMP架构+搭建论坛)

一、Web基础 1.HTML概述 HTML&#xff08;Hypertext Markup Language&#xff09;是一种标记语音,用于创建和组织Web页面的结构和内容&#xff0c;HTML是构建Web页面的基础&#xff0c;定义了页面的结构和内容&#xff0c;通过标记和元素来实现 2.HTML文件结构 <html>…

压缩pdf文件大小在线,在线免费压缩pdf

在现在办公中&#xff0c;PDF文档已经成为我们日常工作中不可或缺的一部分。然而&#xff0c;随着文档内容的不断丰富&#xff0c;PDF文件的大小也逐渐增大&#xff0c;这不仅占用了大量的存储空间&#xff0c;而且在传输和共享时也显得尤为不便。所以有时候我们需要把pdf压缩小…

文本三剑客之awk

awk 按行取列 awk默认的分割符&#xff1a;空格&#xff0c;tab键&#xff0c;多个空格自动压缩成一个 awk的工作原理&#xff0c;根据指令信息&#xff0c;逐行读取文本内容&#xff0c;然后按照条件进行1格式化输出 awk的选项&#xff1a; -F 指定分割符&#xff0c;默认就是…

Git回滚到某次提交

要在Git中回滚到某次提交&#xff0c;你可以使用git reset命令。但是&#xff0c;你需要明确你想要进行的是“软回滚”&#xff08;soft reset&#xff09;&#xff0c;“混合回滚”&#xff08;mixed reset&#xff09;还是“硬回滚”&#xff08;hard reset&#xff09;&…

# Kafka_深入探秘者(4):kafka 主题 topic

Kafka_深入探秘者&#xff08;4&#xff09;&#xff1a;kafka 主题 topic 一、kafka 主题管理 1、kafka 创建主题 topic 命令 1&#xff09;命令&#xff1a; # 切换到 kafka 安装目录 cd /usr/local/kafka/kafka_2.12-2.8.0/# 创建一个名为 heima 的 主题 bin/kafka-topic…

揭秘!速卖通卖家如何靠自养号测评打造爆款?

然而&#xff0c;许多商家对测评的认识存在严重的误区&#xff0c;他们错误地以为仅仅通过几次草率的测评就能快速塑造出爆款产品。实际上&#xff0c;测评远非如此简单&#xff0c;它是一个需要深思熟虑、精心策划和持续投入的过程。测评的真正价值在于帮助平台精准地把握产品…

【C语言课程设计】员工信息管理系统

员工信息管理系统 在日常的企业管理中&#xff0c;员工信息的管理显得尤为重要。为了提高员工信息管理的效率&#xff0c;我们设计并实现了一个简单的员工信息管理系统。该系统主要使用C语言编写&#xff0c;具备输入、显示、查询、更新&#xff08;增加、删除、修改&#xff…

数字排列问题

题目&#xff1a;有1、2、3、4个数字&#xff0c;能组成多少个互不相同且无重复数字的三位数&#xff1f;都是多少&#xff1f; 代码&#xff1a; #include <stdio.h> int main() { int count 0; // 计数器&#xff0c;记录生成的三位数的数量 // 使用三个嵌套的fo…

代数扩张次数关系定理

【单扩域同构引理】 对于单扩张 K / F \mathbb{K/F} K/F有同构 F [ a ] ≅ F [ x ] / ⟨ f ( x ) ⟩ \mathbb{F}\lbrack a\rbrack\mathbb{\cong F}\lbrack x\rbrack/\left\langle f(x) \right\rangle F[a]≅F[x]/⟨f(x)⟩&#xff0c;其中 a ∈ K a \in \mathbb{K} a∈K为本原元…

Java-LinkedList和ArrayList的区别、Get/Add操作性能分析以及常见的遍历方式

LinkedList和ArrayList的区别、Get/Add操作性能分析以及常见的遍历方式 一、LinkedList基本特性主要方法 二、ArrayList初始化及基本操作ArrayList注意点&#xff08;待完善&#xff09;代码示例 三、ArrayList与LinkedList的区别四、Get/Add操作性能分析五、LinkedList遍历方式…

中霖教育:二级建造师报名后缺考有影响吗?

在完成二级建造师的报名程序后&#xff0c;考生无法进行退考。如果是不参加考试&#xff0c;可以选择弃考。弃考对个人并没有负面影响&#xff0c;缺席考试的话也不会被记录在个人诚信档案中。当然&#xff0c;如果弃考的话此次考试的成绩将被记为0&#xff0c;下一年参加考试按…

机器学习项目实战 项目详解 + 数据集 + 完整源码+ 项目报告

前言 本专栏为大家整理了一些机器学习项目&#xff0c;内包含了各种不同的入门级机器学习项目&#xff0c;包含项目的源代码、数据集、以及详细的讲解&#xff0c;每个项目都带有完整的代码数据集报告 项目链接 【机器学习项目实战&#xff08;一&#xff09;】基于随机森林…

关于电机的线性思考

当大多数工程师听到电机这个词时&#xff0c;他们自然地想到旋转装置&#xff0c;例如有刷直流、无刷直流、步进电机或变频原动机。但是电机不一定是旋转的&#xff0c;很多时候设计需要直线运动。一种解决方案是添加某种齿轮或皮带装置来转换旋转运动&#xff0c;这种解决方案…

基于SpringBoot的实习管理系统设计与实现

你好呀&#xff0c;我是计算机学姐码农小野&#xff01;如果有相关需求&#xff0c;可以私信联系我。 开发语言&#xff1a; Java 数据库&#xff1a; MySQL 技术&#xff1a; SpringBoot框架&#xff0c;B/S模式 工具&#xff1a; MyEclipse&#xff0c;Tomcat 系统展示 …

预备役二招算法测试题解

这次题目出的都是一些偏向于基础的题目&#xff0c;就是一些简单的模拟&#xff0c;思维&#xff0c;以及基础算法&#xff08;二分&#xff0c;前缀和&#xff09; &#xff08;点击题目标题&#xff0c;进入原题&#xff09; 我是签到题 题解&#xff1a;就是说给你 t 组数据…

每日鲜语携手中国国家高尔夫球队队员殷若宁征战巴黎,打响中国高端鲜奶品牌“鲜”声量

近日&#xff0c;高端鲜奶品牌每日鲜语宣布携手蒙牛品牌代言人、中国国家高尔夫球队队员殷若宁&#xff0c;共赴巴黎奥运赛场&#xff0c;为梦想挥杆而上。邀请众多消费者开启高品质、健康的生活方式。此举不仅彰显了每日鲜语作为高端鲜奶新标杆的品牌定位&#xff0c;也同时延…

vue2.0项目安装依赖 sass 报错

1、报错代码&#xff1a; 2、原因&#xff1a;项目有点老&#xff0c;vue2的版本&#xff0c;所以node-sass在npm安装的时候大概率的会安装出错&#xff0c;或下载时间过长&#xff0c;因此考虑用dart-sass来替换。 npm install node-sassnpm:dart-sass3、然后就可以成功运行了…

leetcode144、145、94二叉树的前、中、后序遍历

本文主要讲解二叉树的前、中、后序遍历的要点与细节&#xff0c;按照步骤思考更方便理解 c代码如下&#xff0c;末尾 具体要点&#xff1a; 1. 首先我们要了解二叉树的前序&#xff0c;中序&#xff0c;后序的遍历顺序&#xff1a; 前序&#xff1a;中 左 右 中序&a…