一、源碼解讀
tornado是facebook開源的非阻塞web容器,類似java的netty,tornado.options是負責解析tornado容器的全局參數的,同時也能夠解析命令行傳遞的參數和從配置文件中解析參數。使用步驟如下:
1. 源碼中的示例代碼,定義全局變量:
from tornado.options import define, options define("mysql_host", default="127.0.0.1:3306", help="Main user DB") define("memcache_hosts", default="127.0.0.1:11011", multiple=True, help="Main user memcache servers") def connect(): db = database.Connection(options.mysql_host) ...
2. 在模塊的main函數中解析命令行參數或者配置文件
Your ``main()`` method can parse the command line or parse a config file with either:: tornado.options.parse_command_line() # or tornado.options.parse_config_file("/etc/server.conf")
命令行參數格式:--myoption=myvalue
配置文件可以是python文件,參數格式為:
myoption = "myvalue" myotheroption = "myothervalue"
3. Tornado.options默認是定義為單例模式的,通過tornado.options.options對象來維護全局參數,如果在線程中需要維護自己的變量,也可以使用tornado.options. OptionParser對象來維護參數。tornado.options.options就是通過實例OptionParser的對象來實現的,而且把define、parse_command_line、parse_config_file放到tornado.options 包中,可以直接使用,與調用tornado.options.options的方法是一致的。代碼如下:
options = OptionParser() """Global options object. All defined options are available as attributes on this object. """ def define(name, default=None, type=None, help=None, metavar=None, multiple=False, group=None, callback=None): """Defines an option in the global namespace. See `OptionParser.define`. """ return options.define(name, default=default, type=type, help=help, metavar=metavar, multiple=multiple, group=group, callback=callback) def parse_command_line(args=None, final=True): """Parses global options from the command line. See `OptionParser.parse_command_line`. """ return options.parse_command_line(args, final=final) def parse_config_file(path, final=True): """Parses global options from a config file. See `OptionParser.parse_config_file`. """ return options.parse_config_file(path, final=final)
二、應用
# 在tornado.options.options配置變量名 from tornado.options import define, options define('debug', default=True, help='enable debug mode') define('project_path', default=sys.path[0], help='deploy_path') define('port', default=8888, help='run on this port', type=int) # 從命令行中解析參數信息, 如 python web.py --port=9002, 這里的port解析 tornado.options.parse_command_line()
使用參數
使用options獲取剛設置的參數 from tornado.options import options .... application.listen(options.port) ..... settings = { 'debug': options.debug, }
完整代碼
#!/usr/bin/env python # -*- coding: utf-8 -*- # vim: set et sw=4 ts=4 sts=4 ff=unix fenc=utf8: __author__ = 'okker.ma@gmail.com' import tornado.ioloop import tornado.web import os from tornado.options import options, define #在options中設置幾個變量 define('debug', default=True, help='enable debug mode') define('port', default=9002, help='run on this port', type=int) # 解析命令行, 有了這行,還可以看到日志... tornado.options.parse_command_line() class MainHandler(tornado.web.RequestHandler): def get(self): self.write("hello,a world") settings = { 'debug': options.debug, 'gzip': True, 'autoescape': None, 'xsrf_cookies': False, 'cookie_secret': 'xxxxxxx' } application = tornado.web.Application([ (r'/', MainHandler) ], **settings) if __name__ == '__main__': application.listen(options.port) tornado.ioloop.IOLoop.instance().start()
運行:
python web.py --port=9002 --debug=True
示例二

#!/usr/bin/env python # -*- coding:utf-8 -*- import tornado.httpserver import tornado.ioloop import tornado.web from tornado.options import define, options from test import aa define('config', default=None, help='tornado settings file', type=str) options.parse_command_line() if options.config: # print(options.settings) aa() else: raise Exception("You must add a xxx.py at settings/ folder, then run: 'python app.py --settings=user'") class IndexHandler(tornado.web.RequestHandler): def get(self): greeting = self.get_argument('greeting', 'Hello') self.write(greeting + ', friendly user!') if __name__ == "__main__": app = tornado.web.Application( handlers=[(r"/", IndexHandler)] ) http_server = tornado.httpserver.HTTPServer(app) http_server.listen(8000) tornado.ioloop.IOLoop.current().start()

from tornado.options import options import importlib # db_config = importlib.import_module('settings.%s.db_config'%options.settings) # # options.config = { # 'MONGO': db_config.MONGO, # 'SETTINGS': {}, # } def aa(): data = dict(options.items()) print("asdfasdf", data["config"])
注意 tornado如果啟動多進程, option方法是不可實現的, 報錯
tornado.options.Error: Option 'lalala' already defined in app.py
沒找到解決辦法
本文參考鏈接:(其實這篇是抄的, 哈哈哈)
1. https://blog.csdn.net/wgw335363240/article/details/50755782
2. https://my.oschina.net/jiemachina/blog/204875
三、多進程解決辦法 ---》哈哈哈,找到解決辦法啦~
怎么解決呢?,單利模式嘛,哈哈哈
一定要把options的東西放啟動腳本的最上面, 要不下面調用的時候報錯
問題出在哪呢?
多進程是啟動多個,當已經define定義key的時候, OK, 可是同時啟動多個啊, memory中已經有定義好的define的你定義的key了呀
判斷一下嘛, 就好啦

#!/usr/bin/env python # -*- coding:utf-8 -*- from tornado.options import define, options try: if options.lalala: pass except: define('conf', default='zk_css.cnf', help='tornado settings file', type=str) import tornado import tornado.ioloop import tornado.web import os, sys from tornado.httpserver import HTTPServer from tornado.options import define, options from controllers.home_handlers import My404, write_error from common.util.include_url_model import url_wrapper, include from common.base import Config ServerPort = Config().get_content("server") define("port", default=ServerPort["serverport"], type=int) options.parse_command_line() _ROOT_PATH = os.path.dirname(__file__) ROOT_JOIN = lambda sub_dir: os.path.join(_ROOT_PATH, sub_dir) router = url_wrapper([ (r'', include('urls')), ]) settings = dict( template_path=ROOT_JOIN('views'), static_path=ROOT_JOIN('static'), # cookie_secret=Env.COOKIE_SEC, default_handler_class=None, debug=False ) tornado.web.RequestHandler.write_error = write_error application = tornado.web.Application(router, **settings) if __name__ == "__main__": server = HTTPServer(application, max_buffer_size=504857600) server.bind(options.port, address="0.0.0.0") server.start(10) # Forks multiple sub-process tornado.ioloop.IOLoop.current().start()

#!/usr/bin/env python # -*- coding:utf-8 -*- import configparser import os, json, base64 from decimal import Decimal import datetime, time import pymongo # import MySQLdb import pymysql from common.log.loger import Logger import datetime, time, uuid, re import hashlib from common.error import * from other_url import BaseConf from tornado.options import define, options def my_options(arg): return dict(options.items())[arg] class Config(object): """ # Config().get_content("user_information") """ def __init__(self): # file_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), "conf", BaseConf.BaseCnf) file_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), "conf", my_options("conf")) self.cf = configparser.ConfigParser() self.cf.read(file_path) def get_sections(self): return self.cf.sections() def get_options(self, section): return self.cf.options(section) def get_content(self, section): result = {} for option in self.get_options(section): value = self.cf.get(section, option) result[option] = int(value) if value.isdigit() else value return result
分割線
==========================================
屁, 他娘的,根本沒解決,大爺的, 問題出在哪兒了,百度FORK() 函數,跟他有關
解決辦法
#!/usr/bin/env python # -*- coding:utf-8 -*- from tornado.options import define, options if "conf" in dict(options.items()): pass else: define("conf", default='zk_css.cnf', help='tornado settings file', type=str) import tornado.web import os from tornado.httpserver import HTTPServer from tornado.options import define, options from controllers.home_handlers import My404, write_error from common.util.include_url_model import url_wrapper, include from common.base import Config ServerPort = Config().get_content("server") define("port", default=ServerPort["serverport"], type=int) options.parse_command_line() _ROOT_PATH = os.path.dirname(__file__) ROOT_JOIN = lambda sub_dir: os.path.join(_ROOT_PATH, sub_dir) router = url_wrapper([ (r'', include('urls')), ]) settings = dict( template_path=ROOT_JOIN('views'), static_path=ROOT_JOIN('static'), # cookie_secret=Env.COOKIE_SEC, default_handler_class=None, debug=False ) tornado.web.RequestHandler.write_error = write_error application = tornado.web.Application(router, **settings) if __name__ == "__main__": from tornado.netutil import bind_sockets from tornado.process import fork_processes from tornado.ioloop import IOLoop sockets = bind_sockets(port=options.port, address="0.0.0.0") fork_processes(10) server = HTTPServer(application, max_buffer_size=504857600) server.add_sockets(sockets) IOLoop.current().start()
分割線
===========================================
草,又特么不行了,為什么呢? 因為出現了兩種不同結果, 麻痹的, 沒找到解決辦法
root@corleone:/opt/code/my_code/zk_css# python3 app.py --port=8010 --conf=zk_css_2.cnf base: zk_css.cnf base: zk_css.cnf base: zk_css.cnf ----》 看這兒 base: zk_css.cnf base: zk_css_2.cnf --》 看這兒 base: zk_css_2.cnf base: zk_css_2.cnf /usr/local/lib/python3.5/dist-packages/statsmodels/compat/pandas.py:56: FutureWarning: The pandas.core.datetools module is deprecated and will be removed in a future version. Please use the pandas.tseries module instead. from pandas.core import datetools base: zk_css_2.cnf base: zk_css_2.cnf base: zk_css_2.cnf base: zk_css_2.cnf base: zk_css_2.cnf base: zk_css_2.cnf base: zk_css_2.cnf base: zk_css_2.cnf zk_css_2.cnf 8010 [I 180906 16:56:49 process:133] Starting 10 processes