写函数的时候,很多开发者都遇到过变量莫名其妙读取不到,修改之后数值不生效,同样的变量名,在函数内外结果完全不一样。绝大多数这类问题根源,都来自变量作用域。搞懂全局变量、局部变量的生效范围,就可以解决绝大多数变量取值错乱的难题。
作用域就是变量可以被访问到的有效范围。并不是定义完变量,整个程序任意位置都能读写。写在整个脚本顶层的属于全局变量,整个脚本都可以读取访问;写在函数内部创建出来的变量,属于局部变量,仅仅只能在当前函数内部生效,函数运行结束之后局部变量就会销毁,函数外部无法读取。
读取规则相对简单,函数内部读取变量,优先在自己局部空间查找,如果找不到,就向外去全局作用域寻找。但修改赋值逻辑不一样,如果直接在函数内部对全局变量做赋值,Python会默认把它当作全新的局部变量,而不是修改外面的全局变量,直接运行就会触发报错。想要在函数内部修改全局变量,就需要特殊声明。
除了全局、局部,还有嵌套函数带来的非局部作用域。当函数里面还嵌套定义子函数,子函数访问外层父函数的变量,既不属于局部也不属于全局,就是非局部作用域,同样需要专门声明才可以修改外层变量。
新手高频踩坑点:第一,混淆读取和修改,读全局变量不需要声明,修改赋值才需要;第二,尽量不要大量使用全局变量,全局变量随处可修改,多处改动同一个全局变量,调试追踪数据变化非常麻烦;第三,尽量减少同名变量,内外作用域使用完全一样的变量名字,会造成变量遮蔽,局部变量把全局变量覆盖,造成难以察觉bug。
工程开发当中更推荐的思路,尽量少依赖全局变量。函数所需要的数据,通过参数传入,计算结果通过return返回。把数据封闭在函数内部,数据流转清晰可控,降低程序出错概率。
理清变量作用域,分清读取、修改的区别,规避变量遮蔽。遇到变量取值异常,先思考这个变量处在哪个作用域。掌握作用域规则,是写好函数、排查诡异变量bug的必备知识。
