如何初始化python对象一次并在其他模块之间共享?

时间:2013-02-19 21:07:26

标签: python namespaces python-module

对于我的生活,我发现我的蟒蛇过渡非常令人沮丧。我尝试做的其中一件事是从配置字典初始化一个类的单个实例,然后在其他模块中访问该类。

我所面临的问题/我所采取的方法并没有成功,我希望有人可以采用正确的“pythonic”方法。

首先关闭我的应用程序可以作为twistd插件的一部分进行初始化,也可以作为独立脚本进行初始化。

import resource
class App(object):
  _config = None
  _someotherobject = None
  def __init__(self, config):
    self._config = config
    ....

def main():
  global myapp
  myapp = App({}) # Could use help here, how to pass config to it

myapp = None #Global doesnt work as I expect, it doesnt modify this instance, stays as None
if __name__ == '__main__':
  main()


#-----------resource.py
class Foo(object):
  def foo(self):
    app.myapp.somefunction() #NoneType object has no attribute

我已经验证了app对象是在其他模块中的代码启动之前创建的。我只是无法弄清楚为什么模块中的'全局'实例实际上并没有达到我的预期,也混淆了如何从另一个模块引用实例。

-----编辑------ 为了澄清几点,使用python app.py调用脚本 app.py引用了一个名为resources.py的模块,它是一组类定义。在某些类中,执行时,它们引用app.myapp的“singleton”实例。

3 个答案:

答案 0 :(得分:3)

只有在从其他模块导入时才会将main作为独立脚本调用。

if __name__ == '__main__':
  main()

是否可以从命令行运行模块。

证明它

import app
app.main()

然后运行你的代码。

一旦你初始化它app变得像一个单身人士,导入它的任何其他模块将获得初始化版本。

我有一个类似的问题,我不想访问app,但希望模块能够说app = MyApp()并仍然共享相同的数据(我忘了为什么我想要它但它可能与第一次使用时想要初始化有关)

我最终使用了Borg而不是单身人士。

答案 1 :(得分:0)

你最大的问题是sotapme提到的问题。如果您实际上没有将app.py作为顶级脚本运行,那么您没有任何代码调用app.main(),因此没有任何初始化全局的代码。

除此之外,“如何从另一个模块引用实例”非常简单,如果你知道一件简单的事情:

在Python中,全局变量是命名空间。

更具体地说,在您的其他模块中,只需import app,然后访问全局app.myapp

使用__name__ == '__main__'技巧,正如sotapme所解释的那样,意味着您可以import app多次,而不必每次都运行main()函数。

特别是,当你运行它时:

python app.py

Python解释器将加载app.py并将__name__设置为'__main__',因此if语句将触发,这将导致(模块级)全局变量myapp设置为App({})

现在,当resource.py执行import app时,其__name__将设置为app,因此if语句不会触发器,因此您将构造一个新的App并替换全局。从resource.py中的代码中,您可以使用app.myapp,并且您将访问app.py中代码为myapp的相同对象。


您还需要帮助才能将配置传递给App构造函数。我不确定你的问题在这里。你传递一个空的dict作为配置。如果您要传递不同的dict,请使用它。而不是:

myapp = App({}) # Could use help here, how to pass config to it

这样做:

myapp = App(configdict)

如果您的问题是知道如何获取configdict,那么这取决于信息的来源。

如果您正在尝试解析用户可编辑的配置文件,configparser模块适用于传统的.ini风格文件,并且文档具有解释如何处理其他常用格式的链接。< / p>

如果您尝试从命令行构建配置信息,请参阅argparse

如果您想允许环境变量与上述任何一个进行交互(例如,MYAPP_CONFIG可能会告诉您的configparser代码加载不同于正常的配置文件,或者MYAPP_CACHE_DIR可能会为--cachedir的{​​{1}}命令行参数提供不同的默认值,您可以在os.environ中获取值,但必须编写自己的代码来对它们执行任何操作。< / p>

答案 2 :(得分:0)

为了清理一下,这是一个例子:

class App:
    _config = None
    _someotherobject = None

def __init__(self, config):
    self._config = config

def main():
  myapp = App(config) # pass a config object to App

if  __name__ =='__main__':main()

从其他应用中,您必须执行以下操作:

from first_app import App

myapp = App(config)