考虑以下代码:
mod.py
--------
x = 1
main.py
--------
1: from importlib import reload
2: import mod as mod1
3: mod1.x = 2
4: import mod as mod2
5: print(mod2.x)
6: reload(mod2)
7: print(mod1.x)
第2行创建一个mod
对象,并将其分配给mod1
。第4行为mod1
命名了mod2
的别名。第5行打印2
,因为mod2
是对与mod1
相同的对象的引用,该对象由第3行更新。第6行使用对象mod2
重新加载mod.py。 ,而第7行则显示1
。
如何重新加载?第6行还更新了mod1,它怎么知道mod1是mod2的别名?是否有某种机制可以找出给定名称的同义词?
答案 0 :(得分:1)
在python中没有别名,只有names that refer to values。人们喜欢使用as
关键字别名来调用语句,但是import mod as mod1
本质上只是import mod; mod1 = mod; del mod
的简写。
由于存在实际问题,模块有点特殊情况,对import
机制的特殊性的绊脚石是python经验的大部分。导入模块的方式使它们的行为像单例一样,因此某个模块import
的每个mod
语句都引用mod
的相同实例。
每当您尝试导入模块时,解释器都会首先检查sys.modules
,如果它是在运行的会话中首次导入的,它将添加到该位置。
当你说
第2行创建一个
mod
对象,并将其分配给mod1
。
实际发生的是
第2行为此会话加载模块
mod
,并将其引用绑定到名称mod1
。
测试两个名称的身份的一种方法是is
关键字:
>>> import mod as mod1
>>> import mod as mod2
>>> mod1 is mod2
True # they are not only equal, they are the same
>>> from importlib import reload
>>> reload(mod1)
<module 'mod' from '/user/mod.py'>
>>> mod1 is mod2
True # still the same
给出您的初始示例,很难或什至无法保存单个模块的两个不同实例(它们也不能用copy.copy
复制)-您最好实现如下功能而是一个对象。