如何从另一个模块的对象中更改模块变量的值?

时间:2016-01-04 15:55:02

标签: python

摘要:我有一个公开(1) a dict的脚本,我需要从另一个模块修改此dict < / p>

注意similar question的两个很好的答案解释了模块之间的变量范围,但我不明白这是如何适用于我的情况。

在下面的代码中,我希望我能够在mainmodule.py内修改container变量submodule.py,但事实并非如此。为什么呢?

如何在mainmodule内解决container submodule个{?}}实例?

主脚本的代码

# mainmodule.py
# the main script which ultimately exposes the module variable 'container'
import submodule

container = dict()

class MainClass:
    def __init__(self):
        self.sub = submodule.SubClass()

    def set(self, number):
        print("main: container was {container}".format(container=container))
        container['x'] = number
        print("main: container is {container}".format(container=container))


    def call(self, number):
        self.sub.set(number)

if __name__ == "__main__":
    mc = MainClass()
    # updating container from this script
    mc.set(1)
    # updating container from another module
    mc.call(2)
    # again from this script, to check the updates
    mc.set(3)

导入模块的代码

# submodule.py
import mainmodule

class SubClass:
    def __init__(self):
        pass

    def set(self, number):
        print("sub: container was {container}".format(container=mainmodule.container))
        mainmodule.container['x'] = number
        print("sub: container is {container}".format(container=mainmodule.container))

输出

main: container was {}
main: container is {'x': 1}
sub: container was {}
sub: container is {'x': 2}
main: container was {'x': 1}
main: container is {'x': 3}

(1)实际代码使用bottle通过container提供json.dumps()

1 个答案:

答案 0 :(得分:4)

稍微盯着你的代码,我想我知道什么可能会让你失望。作为python foo.py调用的python脚本最终将成为名为sys.modules的模块(在__main__中)。这意味着mainmodule.py节目的底部位被加载并编译并运行一次,使用__name__ == "__main__",这会导致一些事情发生。该模块导入尚未导入的submodule,以便加载并运行。

submodule反过来尝试导入mainmodule。虽然之前已经执行过该文件,但解释器并不知道该模块名称,因此mainmodule.py再次运行,这次使用__name__ == "mainmodule"(与"__main__"不同,所以跳过底部的if套件。)

这意味着您有两个副本container,一个在模块中,其名称为__main__,另一个在名为mainmodule的模块中。两者都来自名为./mainmodule.py的文件这一事实并不重要。

有几种方法可以解决这个问题。一种是立即导入真实,如:

# mainmodule.py
import submodule
class Foo:
    pass
if __name__ == "__main__":
    import mainmodule
    mainmodule.Foo()

另一种选择是将if内的代码移动到另一个文件。