我有三个模块:
constants
,其中包含已加载的配置和类中的其他内容main
,在运行时初始化constants
user
,导入constants
并访问其配置。 constants
模块(简化)如下所示:
class Constants:
def __init__(self, filename):
# Read values from INI file
config = self.read_inifile(filename)
self.somevalue = config['ex']['ex']
def read_inifile(self, filename):
# reads inifile
constants: Constants = None
def populate_constants(filename):
global constants
constants = Constants(filename)
一个应该保持配置的简单对象,没有任何开创性的。
在程序启动时从populate_constants()
调用函数main
。
现在奇怪了 - 当我从constants
导入user
模块时,constants
为None
:
from toplevelpkg.constants import constants
print(constants)
None
但是,如果我像这样导入它,constants
会按照人们的预期进行初始化:
from toplevelpkg import constants
print(constants.constants)
<trumpet.constants.Constants object at 0x035AA130>
为什么?
编辑:在我的代码中,尝试阅读constants
的函数是通过await loop.run_in_executor(None, method_needing_import)
异步运行的。不确定这是否会引起问题?
(作为一个附带问题,有一个配置保持对象解析配置文件并将其作为成员变量提供是一个好习惯吗?)
答案 0 :(得分:2)
之间确实存在差异
from mymodule import obj
(...)
do_something_with(obj)
和
import mymodule
(...)
do_something_with(mymodule.obj)
在第一种情况下,它充当:
import mymodule
obj = mymodule.obj
del mymodule
这意味着此时,在当前模块中,obj
是一个&#34;全局&#34; (在python实际上意味着&#39;模块级别&#39;,而不是&#39;应用程序范围内的)名称绑定到导入时的所有mymodule.obj
(在您的情况下:None
)。从那时起,mymodule.obj
和模块本地obj
名称存在于不同的名称空间(mymodule
名称空间中的第一个名称空间,当前模块名称空间中的第二个名称空间),以及重新绑定{{ 1}}从任何地方都不会改变当前模块mymodule.obj
所绑定的内容。实际上,它就像你在做这件事一样:
obj
在第三个声明之后,a = 2
b = a
a = 4
显然仍然绑定到b
- 重新绑定2
到a
不会影响4
。
在第二种情况下(b
),在导入模块的命名空间中绑定的是整个import mymodule
对象,因此如果mymodule
被反弹(从mymodule.obj
或其他任何地方),更改将在导入模块中可见。在这种情况下,它等同于
mymodule
在这种情况下,a = {"x": 2}
b = a
a["x"] = 4
也会显示更改,因为b["x"]
和a
仍然绑定到同一个对象。