混淆 python 变量作用域

Confusing python variable scope

我通常不会对 python 中的变量范围考虑太多,但我想看看是否有对此的明确解释。给定两个名为 main.pyutils.py 的文件:

utils.py

def run():
    print(L)

main.py

import utils

def run():
    print(L)

if __name__ == '__main__':
    L = [1,2]
    run() 
    utils.run() 

main.py 中的第一个 run() 调用运行良好,尽管 L 没有被送入 run(),并且 utils.run() 调用引发了 NameError. L 是否是可用于 main.py 中定义的所有函数的全局变量?

如果我用 from utils import * 而不是 import utils 导入 utils,这会改变什么吗?

参见Python's FAQ。他们对作用域的实现是全局变量的便利性和危险性之间的折衷。

如果变量仅被函数引用,则变量将被视为全局变量,如果要编辑它们,则需要在函数主体内明确声明为全局变量(例如 global foo )。如果您编辑 run() 以尝试更改 L 的值,则会出现错误。

这里发生的事情是您的 Python 代码导入实用程序,然后运行 ​​run()。此函数发现您正在寻找一个名为“L”的变量,并检查您的全局命名空间。

这是模块级作用域。模块中定义的全局变量可用于同一模块中定义的所有函数(如果未被覆盖)。另一个模块中的函数无法访问另一个模块的变量,除非它们导入它们。

关于“如果我使用 from utils import * 而不是 import utils 导入 utils,这会改变什么吗?”: 否。范围在解析时确定。

检查 this 获取更多信息。

值得注意的是:

It is important to realize that scopes are determined textually: the global scope of a function defined in a module is that module’s namespace, no matter from where or by what alias the function is called. On the other hand, the actual search for names is done dynamically, at run time [...]

因此,模块中定义的变量的两个函数的全局范围是它们在其中定义的模块。首先,它的模块后来也有它使用的全局变量的定义,但另一个模块没有,当函数为 运行 时需要检查变量时,每个人都检查自己模块的变量定义,一个找到了,另一个没有。