2015-03-10 2 views
0

Как получить код для запуска, когда модуль импортируется при запуске веб-приложения CherryPy, а не при создании нового 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 создается, так cherrypy.quickstart() происходит только один раз.

App1 \ App1.py

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', поэтому новый Monitor запускается и новое соединение с базой данных создается как при запуске сервера и на Process(target=some_func).start() ,

ответ

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, но это действительно проблема.

0

Код, который не находится в пределах метода или класса будет работать на импорт, так что если у вас есть файл x.py, который говорит только:

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

и у вас есть еще один файл, как ваша импортирующих этот файл, вы увидите отпечаток этого текста еще до запуска основного или init.

[Редактировать] Чтение назад мой ответ немного вообще возможно, но из-за этого ваш код вне класса или функции:

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

Будет работать на импорт, а также.

+0

Я знаю ... отсюда мой вопрос – stenci