Python 如何在导入的模块之间共享相同的变量
有两个Python脚本:Python 如何在导入的模块之间共享相同的变量,python,Python,有两个Python脚本:master.py和to\u be\u imported.py 这是master.py: import os os.foo = 12345 import to_be_imported 下面是to_be_imported.py: import os if hasattr(os, 'foo'): print 'os hasattr foo: %s'%os.foo 现在,当我运行master.py时,我得到以下结果: os hasattr foo: 1234
master.py
和to\u be\u imported.py
这是master.py
:
import os
os.foo = 12345
import to_be_imported
下面是to_be_imported.py:
import os
if hasattr(os, 'foo'):
print 'os hasattr foo: %s'%os.foo
现在,当我运行master.py
时,我得到以下结果:
os hasattr foo: 12345
指示导入的模块to_be_imported.py
拾取在导入该模块的进程内声明的变量(master.py
)
虽然它工作正常,但我想知道它工作的原因,并确保它是一种安全的做法。如果模块已经导入,则后续导入到模块时将使用模块的缓存版本。即使您通过不同的名称引用它,如下例所示
将操作系统作为导入操作系统
将操作系统作为b导入
两者均指第一次导入的同一os
模块。因此,很明显,分配给模块的变量将被共享
您可以使用内置python函数
id()。即使您通过不同的名称引用它,如下例所示
将操作系统作为导入操作系统
将操作系统作为b导入
两者均指第一次导入的同一os
模块。因此,很明显,分配给模块的变量将被共享
您可以使用内置的python函数id()
验证它,从本质上来说,没有什么是坏主意,但您必须记住几件事:
模块是Python中的对象它们只加载一次并添加到sys.modules
。这些对象也可以像普通对象一样添加属性(没有凌乱的setattr
)
>P>因为它们是对象,而不是实例化对象,所以必须将它们视为单体(它们<强>是< /强>单点,毕竟),并且必须考虑这样的模型的缺点和好处:
a。单例只是一个对象。您确定访问它们的属性是并发安全的吗?
B模块是全局对象。您确定可以跟踪整个行为并访问其成员吗?您确定可以在那里调试错误吗
代码是您将与其他人一起使用的吗
虽然没有比其他想法更好的想法,但良好的实践告诉我们,使用全局变量并不常见,特别是如果我们有团队合作的话。另一方面:如果代码是并发和/或可重入的,请避免使用全局变量或依赖模块属性。OTOH分配这样的属性不会有问题。它们将持续到脚本执行的整个生命周期
这里不是选择最佳备选方案的地方。根据您陈述问题的方式,您可以向程序员或codereview提问。您可以选择许多变量来共享状态,而无需在模块中使用全局变量,比如在参数之间来回传递状态中的变量,或者学习并使用OOP。但是,同样地,这个网站没有这样做的余地。从本质上来说,没有什么是坏主意,但你必须记住几件事:
模块是Python中的对象它们只加载一次并添加到sys.modules
。这些对象也可以像普通对象一样添加属性(没有凌乱的setattr
)
>P>因为它们是对象,而不是实例化对象,所以必须将它们视为单体(它们<强>是< /强>单点,毕竟),并且必须考虑这样的模型的缺点和好处:
a。单例只是一个对象。您确定访问它们的属性是并发安全的吗?
B模块是全局对象。您确定可以跟踪整个行为并访问其成员吗?您确定可以在那里调试错误吗
代码是您将与其他人一起使用的吗
虽然没有比其他想法更好的想法,但良好的实践告诉我们,使用全局变量并不常见,特别是如果我们有团队合作的话。另一方面:如果代码是并发和/或可重入的,请避免使用全局变量或依赖模块属性。OTOH分配这样的属性不会有问题。它们将持续到脚本执行的整个生命周期
这里不是选择最佳备选方案的地方。根据您陈述问题的方式,您可以向程序员或codereview提问。您可以选择许多变量来共享状态,而无需在模块中使用全局变量,比如在参数之间来回传递状态中的变量,或者学习并使用OOP。但是,同样,这个网站也没有这样做的余地。os.foo=12345
-像那样弄乱其他模块的属性是一个非常糟糕的主意。请使用真实的事实说明为什么这是一个糟糕的主意。有没有其他“更好”的方法来做到这一点?该模块可能有一个同名的变量,它可能严重依赖于该变量。如果你改变它,你可能会陷入意想不到的行为。谢谢os.foo=12345
-像那样弄乱其他模块的属性是一个非常糟糕的主意。请用事实说明为什么这是一个糟糕的主意。是否有其他“更好”的方法来做到这一点?模块可能有一个同名的变量,它可能严重依赖该变量。如果你改变它,你可能会陷入意想不到的行为。谢谢有没有一种方法可以强制从磁盘导入而不是缓存导入?我从来没有发现过一个用例具有同一模块的两个不同副本。但是,对重新加载功能做一点研究,如果我没记错的话,它声称可以从磁盘刷新模块。我可以想象,如果你正在试验一个修改过的版本,你会想要这样做