为何Python子函数无法访问主函数内部定义的变量?
为什么Python函数无法访问调用它的函数里的局部变量?
这个问题的核心是Python的作用域规则是在函数定义时确定的,而不是调用时,咱们一步步拆解清楚:
先看第一个能正常运行的例子
def abc(): print(a) def main(): abc() if __name__=='__main__': a = 'a' main()
这里的a是定义在全局作用域(顶级代码块)的变量。当abc()执行时,它会按照Python的LEGB作用域查找规则找变量:
- 第一步:自身局部作用域(Local):
abc内部没定义a,跳过 - 第二步:封闭作用域(Enclosing):
abc不是嵌套在其他函数里的,这层没有,跳过 - 第三步:全局作用域(Global):找到了你定义的
a = 'a',直接使用 - 第四步:内置作用域(Built-in):这里用不到
所以自然能顺利打印出a的值。
再看第二个失效的例子
def abc(): print(a) def main(): a = 'a' abc() if __name__=='__main__': main()
这里的a被移到了main()的局部作用域里,但abc()是在全局作用域定义的函数——它的作用域链从定义那一刻就固定了:只能访问自身局部、全局、内置这三层,根本看不到调用它的main()函数的局部变量!
当abc()执行时,按LEGB规则查找:
- 自身局部没有
a - 没有封闭作用域
- 全局作用域里也没定义
a(你把a放到main内部了) - 内置作用域也找不到
a
于是就会抛出NameError: name 'a' is not defined的错误。
怎么解决这个问题?
最符合Python最佳实践的方式是把变量作为参数传递,彻底摆脱对作用域的依赖:
def abc(a): print(a) def main(): a = 'a' abc(a) # 把main里的a直接传给abc if __name__=='__main__': main()
如果非要让abc访问main的局部变量(不推荐,会增加代码耦合性),可以把abc嵌套到main内部定义,这样它的封闭作用域就包含了main的局部作用域:
def main(): a = 'a' def abc(): # 嵌套在main里定义abc print(a) abc() if __name__=='__main__': main()
内容的提问来源于stack exchange,提问作者mrCarnivore
相关产品推荐
相关产品推荐

