对我来说,我发现我的python转换非常令人沮丧。我正在尝试做的一件事是从配置字典初始化一个类的单个实例,然后在其他模块中访问该类。
我所面临的问题/我所采取的方法没有得到解决,我希望有人能用正确的“Python式”方法。
首先,我的应用程序可以初始化为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对象是在启动另一个模块中的代码之前创建的。我只是不明白为什么模块中的“global”实例实际上没有达到我所期望的效果,也不明白如何从另一个模块引用该实例。
----编辑------
为了澄清几点,脚本使用python app.py
调用
py引用了一个名为resources.py
的模块,它是一堆类定义。在某些类中,当执行时,它们引用app.myapp的“singleton”实例。
要稍微清理一下,下面是一个例子:
从另一个应用程序中,您必须执行以下操作:
你最大的问题是索塔普提到的那个。如果实际上没有将
app.py
作为顶级脚本运行,则没有任何代码调用app.main()
,因此没有初始化全局脚本的功能。除此之外,“如何从另一个模块引用实例”非常简单,如果您知道一件简单的事情:
在Python中,globals是有名称空间的。
更具体地说,在其他模块中,只需
import app
,然后以app.myapp
的形式访问全局。正如sotapme所解释的,使用
__name__ == '__main__'
技巧意味着您可以随心所欲地import app
多次,而不必每次都运行main()
函数。特别是,运行此命令时:
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
要传递,请使用它。而不是这个:执行以下操作:
如果你的问题是知道如何获取信息,那取决于信息的来源。
如果您试图解析用户可编辑的配置文件,^{} 模块对传统的.ini样式文件很好,并且文档中有一些链接,可以解释如何处理其他一些流行格式。
如果您试图从命令行建立配置信息,请参见^{} 。
如果您希望允许环境变量与上述任何一个变量交互(例如,} 中的值,但是你必须自己写代码来处理它们。
MYAPP_CONFIG
可能会告诉您的configparser
代码加载一个与普通配置文件不同的配置文件,或者MYAPP_CACHE_DIR
可能会为--cachedir
的命令行参数提供不同的默认值,argparse
),您将获得^{您的
main
将仅作为独立脚本调用,而不是从其他模块导入时调用。是使模块可以从命令行运行的技巧。
为了证明这一点
然后运行你的代码。
一旦初始化了它
app
就会变成一个单例,任何其他导入它的模块都会得到该初始化版本。我有一个类似的问题,我不想访问
app
,但希望模块能够说app = MyApp()
,并且仍然共享相同的数据(我忘记了为什么我想要它,但这可能与希望它在首次使用时初始化有关)我最终使用了Borg而不是单例。
相关问题 更多 >
编程相关推荐