有两个Python脚本:master.py
和to_be_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
)内声明的变量。
虽然它工作正常但我想知道它为什么有用,并确保它是一种安全的做法。
答案 0 :(得分:3)
如果已导入模块,则后续导入模块将使用模块的缓存版本。即使您通过不同的名称引用它,如下例所示
import os as a
import os as b
两者都引用了第一次导入的相同os
模块。因此很明显,分配给模块的变量将被共享。
您可以使用内置的python函数id()
答案 1 :(得分:2)
本身没有什么是坏主意,但你必须记住一些事情:
sys.modules
。这些对象也可以像常规对象一样添加属性(没有setattr
的混乱实现)。既然它们是对象,而不是可实例化的对象,你必须将它们视为单例(毕竟它们 单例),你必须考虑这种模型的缺点和好处:
一个。单身人士只是一个对象。您确定访问其属性是并发安全的吗? 湾模块是全局对象。您确定可以跟踪整个行为并访问其成员吗?你确定你能在那里调试错误吗?
代码是否适用于其他人?
虽然没有比其他更好的想法,但是好的做法告诉我们使用全局变量并不是很好看,特别是如果我们有一个团队可以使用。另一方面:如果您的代码是并发和/或可重入的,请避免使用全局变量或依赖模块属性。 OTOH你可以毫无困难地分配这样的属性。它们将持续执行脚本。
这不是选择最佳替代方案的地方。根据您陈述问题的方式,您可以在程序员或代码审查中询问。您可以选择多种变体来共享状态,而无需在模块中使用全局变量,例如在参数内来回传递这些变量,或者学习和使用OOP。但是,再一次,这个网站不是那个范围。