对于我的生活,我发现我的蟒蛇过渡非常令人沮丧。我尝试做的其中一件事是从配置字典初始化一个类的单个实例,然后在其他模块中访问该类。
我所面临的问题/我所采取的方法并没有成功,我希望有人可以采用正确的“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”实例。
答案 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)