main块内声明变量对块内函数的可见性问题及解决方法
关于main块变量与内部函数的可见性问题
咱们先逐个拆解你的问题:
问题1:main块内声明的变量对块内函数的可见性如何?
在if __name__ == "__main__":这个代码块里声明的变量,对于块内定义的函数来说,默认是只读可见的——也就是说,你可以在函数里读取这个变量的值,但如果直接尝试修改它,Python就会触发错误。
举个能正常运行的例子:
if __name__ == "__main__": foo = 0 def bar(): print(foo) # 读取外部变量,不会报错 bar() # 输出0
但像你代码里那样试图修改foo,就会出现问题。
问题2:为何不能修改?以及如何修复代码?
报错原因
当你在函数bar()里写foo +=1时,这本质是一个赋值操作。Python的作用域规则是:如果在函数内部对一个变量进行赋值,会默认把这个变量当作函数的局部变量。但你的代码里,bar()内部并没有先定义foo,直接就去赋值,Python找不到这个局部变量的定义,所以抛出了UnboundLocalError。
修复方法
有两种常用的方式可以解决这个问题:
方法1:用global关键字声明变量
if __name__ == "__main__":块里的foo属于模块级的全局变量,你可以在函数内部用global关键字告诉Python:“这个foo不是我的局部变量,是外面的全局变量”。修改后的代码如下:
if __name__ == "__main__": foo = 0 def bar(): global foo # 声明foo为全局变量 foo += 1 bar() print(foo) # 此时会输出1,符合预期
方法2:用可变对象包装变量
如果你不想用global,可以把foo放在一个可变对象(比如列表、字典)里。因为可变对象的元素修改不属于“变量赋值”,Python会直接引用外部的可变对象,不需要额外声明:
if __name__ == "__main__": foo = [0] # 用列表包装数值 def bar(): foo[0] += 1 # 修改列表的元素,不需要声明 bar() print(foo[0]) # 输出1
内容的提问来源于stack exchange,提问作者user2177304
相关产品推荐
相关产品推荐

