模块重载语义

时间:2019-08-26 12:08:52

标签: python

考虑以下代码:

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的别名?是否有某种机制可以找出给定名称的同义词?

1 个答案:

答案 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复制)-您最好实现如下功能而是一个对象。