直接导入变量产生的值与在Python中导入其模块的值不同

时间:2017-05-04 10:37:23

标签: python python-import

我有三个模块:

  • 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模块时,constantsNone

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)异步运行的。不确定这是否会引起问题?

(作为一个附带问题,有一个配置保持对象解析配置文件并将其作为成员变量提供是一个好习惯吗?)

1 个答案:

答案 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 - 重新绑定2a不会影响4

在第二种情况下(b),在导入模块的命名空间中绑定的是整个import mymodule对象,因此如果mymodule被反弹(从mymodule.obj或其他任何地方),更改将在导入模块中可见。在这种情况下,它等同于

mymodule

在这种情况下,a = {"x": 2} b = a a["x"] = 4 也会显示更改,因为b["x"]a仍然绑定到同一个对象。

wrt /你的问题:是的,有一些&#34; config&#34;对象是一种非常常见的模式。你可能想要确保你可以从头开始构建它#34;也是(我的意思是,不一定来自配置文件)使单元测试更容易。