ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

Python变量同名不同命_函数里外是两个世界

Python变量同名不同命_函数里外是两个世界 你写下了一个全局变量 a , 其被赋值为 100 , 之后在函数内部又写了 a 300 , 满心以为外面的那个 a 同样变成了 300 , 运行之后一看 , 发现完全没有变化 , 依旧是 100。这不是 bug是 作用域在搞鬼。你天天经历的场景, 用公司办公室来类比, 今天就把这件事彻底说清楚。保证你看完再也不会踩坑。一、什么是作用域就是变量在哪能用要知道, 作用域所涉及的范畴, 实际上指的便是变量能够发挥其效用的具体范围。某个变量于何处可以被使用, 于何处又不可以被使用这番情况, 这恰恰是作用域负责管控的相关事宜。将其设想为似一家公司般的存在: 存在一些物品被放置于大厅公告栏之上, 进而全公司范围内的人员均可看见另外存在一些物品被锁在你工位的抽屉当中, 而唯有当你坐在那个位置的时候才会用得上。里主要有两种作用域二、全局变量贴在公告栏上全公司都能看先看最简单的情况。你在文件最外层写了两个变量a 100 b 200放置于全局作用域之中的这两个变量, 便成为了全局变量, 将其张贴在公告栏上, 于当前文件的任意一个位置均可进行访问。函数内部能不能看到它们能。def test(): c 上硅谷 d 你好啊 print(a) # 100能看到 print(b) # 200能看到 print(c) # 上硅谷 print(d) # 你好啊 test()找寻的逻辑为: 首先于当下局部进行查找, 要是未能找到, 便朝着外层去查找, 情形如同当你在工作位置上寻觅不到文件之时, 就抬起头看向公告栏, 如此这般的话, 便能够找到且可以加以使用。然而从相反的方向来看呢? 于全局的所在位置也就是函数的外面去进行打印局部变量 c 以及 d 的操作:print(a) # 100没问题 print(b) # 200没问题 print(c) # 报错NameError: name c is not defined print(d) # 报错NameError: name d is not defined关键准则是, 于函数内部而言, 可以对全局变量展开访问, 也就是朝着外部去看, 然而处于全局的位置时, 却无法获取局部变量, 这就如同没办法去翻动他人工位的抽屉那样。三、翻车现场函数里改了 a外面竟然没变好真正容易踩坑的地方来了。你于全局范围之中, 对 a 进行了定义, 使其取值为 100, 之后呢, 又在函数内部写下了这样的内容, 即 a 被赋值为 300。a 100 def test(): a 300 print(a) # 这里打印多少 test() print(a) # 这里又打印多少函数里的 a 打印 300这个大多数人能猜对。不是函数边界以内的 a 打印数值几? 不少人觉得会是 300, 真的情况成 100 啦。为何会这样呢? 原因在于, 当碰上 a 等于 300 的情况时, 并非是对全局的 a 进行“修改”, 而是于局部作用域当中创建了一个有着相同名称的变量 a。这个局部的 a 与全局的 a 属于两个全然不同的变量, 更改局部的那个 a , 和全局的 a 没有任何关联。以公司来进行类比的情况而言: 在自身所处的工位之上, 你粘贴上了一张书写着“a 300”字样的纸条, 然而公告栏那儿贴着的写明“a 100”的通知, 你连碰都未曾去碰, 你工位上的那张纸条仅仅在你坐在那个位置的时候才具备效力, 公告栏上的通知一直保持着原状丝毫末动。同样会给予你警示: “从外部作用范围之中隐匿了名称 a”, 换句通俗易懂的话来讲就是, “嘿, 兄弟, 要是你这样去编写, 那在函数内部的 a 便与外部的那个 a 不存在关联了”。关键结论只读取全局变量 → 函数里可以直接看往外找想修改全局变量 → 直接写赋值不行会当成定义局部变量四、 关键字明确宣布我要改公告栏上的那真想在函数里修改全局变量怎么办加一个关键字。a 100 def test(): global a # 明确声明这个 a 是全局的那个 a a 300 print(a) # 300 test() print(a) # 300这回真改了这行代码所表达的意思是: 告知关于其内接下来程序中所用到的名为 a 的这个标识符, 表示这里所指的 a 就是处于外层的全局性质的变量 a, 并令不要再去创建其为局部的了。从公司的角度举例来说那便是你手持公章去往公告栏之前, 扯下了放置于上头的那张写着“a等于100”的通知, 替换成了“a等于300”这般情况。而此刻整个公司所瞧见的便都是全新的数值了。记住这个口诀读全局不用声明改全局必须 。五、局部变量的生命周期下班走人工位清空往下是个极易被忽视然而非常关键的细节, 局部作用域以及局部变量于函数调用之际创建, 函数执行完成之后销毁。看这段代码def test2(): m 100 m 1 print(m) # 101 test2() test2() test2()进行三次调用, 每一次调用时打印出来的都是 101, 并不会出现累加成 102、103 的情况。为什么因为每次调用函数都是一次全新的开始步骤发生了什么类比第一次调用 test2()缔造局部作用范围, 使得 m 取值为 100, 之后 m 变为 101, 接着将 101 予以打印, 最后致使其被销毁。上班 → 工位准备好 → 干活 → 下班走人工位清空第二次调用 test2()再次去创建局部作用域, 接着 m 等于 100 , 随后 m 变为 101 , 然后打印数字 101 , 最后进行销毁。第二天去上班, 到了新工位, 此新工位与昨天毫无关联, 然后开始干活, 干完活后便下班离开。第三次调用 test2()又一次再次进行创建, 使得m的值变为100, 接着m的值又变成了101, 随后将101进行打印, 最后把相关内容进行销毁。第三天……同上每一回调用终结, 局部变量便被消毁了, 恰似下班后保洁婶婶将你工位之上的事物全都丢弃了。下一回上班再度调动, 所有一切皆从头开始, 跟先前未曾存有任何关联。即便调用一百次, 每回 m 俱是一百零一。六、全局变量的生命周期公司开门到关门处于“上下班”标准的, 是局部变量, 而属于“公司开/关门”范畴的, 则为全局变量。全局作用域和全局变量在程序开始运行时创建程序结束后销毁。看这段代码n 100 def test3(): global n n 1 print(n) test3() # 打印 101 test3() # 打印 102 test3() # 打印 103 print(n) # 打印 103这回跟上面那个test2不一样, 每次调用的时候, n都在往上涨, 因为n是全局变量, 声明之后, 每次修改的都是公告栏上同一个n。执行流程拆解阶段全局变量 n说明程序开始100全局作用域创建n 定义为 100第一次调用 test3()100 → 101构造局部作用域, 声明之后, 执行 n 加上 1 的操作, 打印出 101, 随后销毁局部作用域。第二次调用 test3()101 → 102局部作用域被重新创建, n 依旧是那个处于全局状态的 n其值为 101, 加上 1 之后便变为 102, 在打印完成后局部作用域被销毁。第三次调用 test3()102 → 103同上n 变 103打印后局部销毁打印 n103全局的 n 此时是 103程序结束销毁全局作用域和所有全局变量全部销毁再度运行程序会出现何种情况呢? n 再度自 100 起始。鉴于上一次程序终止之后, 全局变量已然被销毁, 恰似手机恢复至出厂设置那般, 一切再度开启。七、两种作用域完整对比对比项全局作用域局部作用域位置文件最外层函数内部变量类型全局变量局部变量能访问谁只能访问全局变量能访问局部变量 全局变量往外找修改全局变量直接改必须加 声明何时创建程序开始运行时函数被调用时何时销毁程序运行结束函数执行完毕多次调用全局变量持续存在每次调用都是全新的跟上次无关公司类比公司公告栏开门到关门你的工位上班到下班总结三句话记住全部核心首先, 于函数里边是能够看到全局变量的, 然而在全局的位置却是看不到局部变量的。这就如同你静坐在工位之上能够抬头去看公告栏的内容, 可是当你站立在公告栏的前面时却没办法去翻动你工位对应的抽屉。其二, 于函数之中直接对全局变量进行赋值操作, 并非是修改, 而是创建一个具有相同名称的局部变量。你仅仅是在工位之上张贴了一张纸条, 对于公告栏上面的通知, 一个字都未曾变动。若想要真正进行修改? 那就加上。第三点, 局部变量是伴随着函数调用而产生的, 随着函数结束而消亡, 每一次都是崭新全新的。全局变量是从程序启动开始存活, 一直到程序结束, 在这期间不会受到局部变量被销毁的影响。把这三条想明白作用域这块就不会再踩坑了。
返回列表