阻止代码在导入时运行

时间:2015-03-10 16:36:59

标签: python multiprocessing cherrypy python-multiprocessing

如何在CherryPy Web应用程序启动时导入模块时运行一些代码,而不是在创建新Process时运行?

我的CherryPy应用程序遵循以下模式:

Main.py

from Api1.Api1 import Api1
from Api2.Api2 import Api2
config = {'global': {'server.socket_host':  '0.0.0.0'}}
class Root():
    global config
    def __init__(self):
        self.app1 = App1('app1')
        self.app2 = App2('app2')
        config.update(self.app1.config)
        config.update(self.app2.config)

if __name__ == '__main__':
    cherrypy.quickstart(Root(), '/', config)

此处if __name__ == '__main__':完成了它的工作:服务器启动时__name__ == '__main__',创建新__name__ == '__mp_main__'Process,{{1}只发生过一次。

App1的\ App1.py

cherrypy.quickstart()

这里同样的技巧不起作用,因为它始终是def every_hour(): [...] Monitor(cherrypy.engine, every_hour, frequency=60 * 60).start() db = peewee.SqliteDatabase('app1.db', threadlocals=True) class App1(): def __init__(self, root_dir): self.root_dir = root_dir my_path = os.path.dirname(__file__) self.config = {'/%s/css' % root_dir: {'tools.staticdir.on': True, 'tools.staticdir.dir': '%s\\css' % my_path}, '/%s/img' % root_dir: {'tools.staticdir.on': True, 'tools.staticdir.dir': '%s\\img' % my_path}} ,因此启动新的__name__ == 'App1.App1'并在服务器启动时和{{1}创建新的数据库连接}。

2 个答案:

答案 0 :(得分:2)

一种选择是将您在App1.py顶层的初始化代码移动到一个函数,然后从if __name__ == "__main__":中的main.py防护中调用该函数:

<强> Main.py

from App1.App1 import App1, app1_init
from App2.App2 import App2
config = {'global': {'server.socket_host':  '0.0.0.0'}}
class Root():
    global config
    def __init__(self):
        self.app1 = App1('app1')
        self.app2 = App2('app2')
        config.update(self.app1.config)
        config.update(self.app2.config)

if __name__ == '__main__':
    app1_init()
    cherrypy.quickstart(Root(), '/', config)

<强> App1.py

def every_hour():
    [...]

db = None
def app1_init():
    global db
    Monitor(cherrypy.engine, every_hour, frequency=60 * 60).start()
    db = peewee.SqliteDatabase('app1.db', threadlocals=True)

class App1():
    def __init__(self, root_dir):
        self.root_dir = root_dir
        my_path = os.path.dirname(__file__)
        self.config = {'/%s/css' % root_dir: {'tools.staticdir.on': True, 'tools.staticdir.dir': '%s\\css' % my_path},
                       '/%s/img' % root_dir: {'tools.staticdir.on': True, 'tools.staticdir.dir': '%s\\img' % my_path}}

这不是很理想,因为导入App1的任何内容都需要知道才能调用app1_init,但它确实可以解决问题。

答案 1 :(得分:0)

不在方法或类中的代码将在导入时运行,因此如果您的文件x.py仅表示:

print("I'm just a poor boy, I need no sympathy")

并且你有另一个像你这样的文件导入这个文件,你甚至可以在main或init启动之前看到这个文本的打印。

[编辑]回读我的答案可能有点笼统,但是因为这样你的代码在一个类或函数之外:

Monitor(cherrypy.engine, every_hour, frequency=60 * 60).start()
db = peewee.SqliteDatabase('app1.db', threadlocals=True)

也将在导入时运行。