整体目标
跨文件使用全局变量,控制一下参数的设置。
问题情景
在某一文件夹下存在三个文件,其中文件test2.py
被test1.py
和test2.py
同时引用。但是因为引用方式不同,导致在整个程序的空间中,出现两个相同路径但名称的不同的模块。此时,在test1
和test3
中导入的test2
不是同一个test2
。
# 文件说明
- test1.py
- test3.py
- test_dic
- test2.py
# path: test_dic/test2.py
x = 10
def print_x():
print(x)
# path: test1
import test_dic.test2
import test3
import sys
print(test_dic.test2.x)
test_dic.test2.x = 20
test_dic.test2.print_x()
test3.print_x()
# path: test3
import sys
sys.path.append("/some_path/test/test_dic")
def print_x():
print(test2.x)
在test1
中,通过相对路径导入test2
模块,此时test2
文件的模块名称为test_dic.test2
,而在test3
中通过先添加系统路径并直接导入test2
方式导入,此时test2
文件的模块名称为test2
,因此在程序中被认为是两个模块。所以在test1
中的变量修改不会影响到test3
,但是会影响到test2
。(所以程序运行时,模块的名称本身就是以主程序为目录的内容)
修改办法
在test1
和test3
中采用相同的模块导入方式。
from test_dic import test2
def print_x():
print(test2.x)
参考内容
python中的命名空间
Python中有三种主要的命名空间:
- 内置命名空间(Built-in Namespace):这是Python解释器默认提供的命名空间,其中包含了内置函数(如
print()
、len()
等)和内置类型(如int
、str
等)。这些名称在任何Python程序中都是可用的,无需导入任何模块。 - 全局命名空间(Global Namespace):全局命名空间是在模块级别定义的命名空间,其中包含了模块级别的变量、函数和类。全局命名空间在整个模块中可见,可以被模块内的任何函数或类访问。
- 局部命名空间(Local Namespace):局部命名空间是在函数或类定义内部创建的命名空间,用于存储局部变量和函数参数。局部命名空间只在所在函数或类的作用域内可见,当函数或类执行完毕后,局部命名空间中的对象将被销毁。
查看程序中导入的所有内容
import inspect
import sys
# 获取当前程序中加载的所有模块
loaded_modules = list(sys.modules.values())
# 遍历所有模块
for module in loaded_modules:
# 获取模块的命名空间
module_namespace = vars(module)
module_name = module.__name__
# 尝试获取模块的源代码文件路径
try:
module_file = inspect.getsourcefile(module)
except TypeError:
module_file = None
if "(built-in)" not in str(module) and "(frozen)" not in str(module) and "(namespace)" not in str(module):
print(str(module))
pass
# 判断模块是否为自己写的代码(排除内置模块和第三方库)
if module_file and module_file.startswith(sys.path[0]):
print("自己写的模块:", module_name)
# 判断模块的命名空间是否为包
if hasattr(module, '__path__'):
package_name = module_name
print("包:", package_name)