Python中导入全局函数与定义全局函数的行为差异问询
先看你给出的代码和输出:
setup.py 代码
good='hello' def isGood(testGood): return testGood == good print(isGood('hello')) print(isGood('bye')) good='bye' print(isGood('bye'))
输出
True False True
main.py 代码
from setup import * print(good) print(isGood('hello')) good='hello' print(good) print(isGood('hello'))
输出
bye False hello False
行为解释
模块内部的变量引用:在
setup.py内部,isGood函数引用的是setup模块自身命名空间中的good变量。每次调用isGood时,Python都会实时去setup模块的全局命名空间查找good的值,所以当你在模块内修改good='bye'后,函数能立刻感知到这个变化,返回True。跨模块导入后的变量引用:当你用
from setup import *导入时,本质是把setup模块里的good和isGood复制到了main.py的本地命名空间中。但isGood函数在定义时,已经绑定了它所在的setup模块的全局命名空间——也就是说,函数内部的good始终指向setup模块里的那个变量,和main.py本地的good是完全独立的两个变量。
你在main.py中修改good='hello',只是修改了main.py自己命名空间里的good,对setup模块里的good没有任何影响(此时setup模块的good还是最后赋值的'bye')。所以两次调用isGood('hello'),都是拿'hello'和setup模块里的'bye'比较,结果自然是False。
官方文档依据
Python的命名解析遵循LEGB规则(Local局部 → Enclosing闭包 → Global全局 → Built-in内置)。对于模块级函数,其引用的“全局变量”特指定义该函数的模块的全局命名空间,而非调用该函数时所在模块的命名空间。这一规则在Python官方文档的「命名和绑定」章节有明确说明:函数定义时会确定全局变量的查找路径,后续无论在哪个模块调用该函数,都会优先访问原模块的全局变量。
内容的提问来源于stack exchange,提问作者Aviram Tal

