Python 模块重新加载语义
考虑以下代码:Python 模块重新加载语义,python,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是对
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
是对与第3行更新的mod1
相同的对象的引用。第6行使用对象mod2
重新加载mod.py,第7行打印1
重新加载究竟是如何工作的?第6行也更新了mod1,它怎么知道mod1是mod2的别名?是否有某种机制可以找出给定名称的同义词?python中没有别名,只有别名。人们喜欢使用
作为
关键字别名调用语句,但是import mod as mod1
本质上只是import mod的简写;mod1=mod;del mod
现在谈到真正的问题,模块是一种特殊情况,在import
机制的特性上绊倒几乎是python体验的一部分。模块的导入方式使它们的行为类似于单例,因此某些模块mod
的每个import
语句都引用了mod
的相同实例
每当您尝试导入模块时,解释器将首先检查sys.modules
,如果在运行会话中第一次导入模块,将在此处添加该模块
当你说
第2行创建一个mod
对象并将其分配给mod1
实际发生的是
第2行加载此会话的模块mod
,并将其引用绑定到名称mod1
可以测试两个名称的标识的一种方法是
is
关键字:
>>将mod作为mod1导入
>>>将mod作为mod2导入
>>>mod1是mod2
没错,他们不仅平等,而且是一样的
>>>从导入lib导入重新加载
>>>重新加载(mod1)
>>>mod1是mod2
没错,还是一样
根据您最初的示例,很难甚至不可能保存单个模块的两个不同实例(它们也不能通过
copy.copy
)进行复制-您最好将您拥有的功能作为一个对象来实现。Python跟踪已加载的模块,如果已加载,则不会重新加载它们。然后将mod2指向与mod1相同的对象。