如何在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}创建新的数据库连接}。
答案 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)
也将在导入时运行。