在你已经学到一些开发基础,并想写你自己的应用了吧?这里有一些Bottle开发小技巧可提高你的生产力。
默认应用
Bottle维护一个全局的 Bottle 实例的栈,模块层面的函数和修饰器使用栈顶实例作为默认应用。例如 route() 修饰器,相当于在默认应用上面调用了 Bottle.route() 方法。
@route('/')def hello():
return 'Hello World'
run()
对于小应用来说,这样非常方便,可节约你的工作量。但这同时意味着,在你的模块导入的时候,你定义的 route 就被安装到全局的默认应用中了。为了避免这种模块导入的副作用,Bottle 提供了另外一种方法,显式地管理应用:
app = Bottle()
@app.route('/')def hello():
return 'Hello World'
app.run()
分离应用对象,大大提高了可重用性。其他开发者可安全地从你的应用中导入 app 对象,然后通过 Bottle.mount() 方法来合并到其它应用中。
0.13 新版功能.
从 bottle-0.13 开始,你可以使用 Bottle 实例作为上下文管理器。
app = Bottle()
with app:
# Our application object is now the default
# for all shortcut functions and decorators
assert my_app is default_app()
@route('/')
def hello():
return 'Hello World'
# Also useful to capture routes defined in other modules
import some_package.more_routes
调试模式
在开发的早期阶段,调试模式非常有用。
bottle.debug(True)
在调试模式下,当错误发生的时候,Bottle会提供更多的调试信息。同时禁用一些可能妨碍你的优化措施,检查你的错误设置。
下面是调试模式下会发生改变的东西,但这份列表不完整:
默认的错误页面会打印出运行栈。
模板不会被缓存。
插件马上生效。
请确保不要在生产环境中使用调试模式。
自动加载
在开发的时候,你需要不断地重启服务器来验证你最新的改动。自动加载功能可以替你做这件事情。在你编辑完一个模块文件后,它会自动重启服务器进程,加载最新版本的代码。
from bottle import runrun(reloader=True)
它的工作原理,主进程不会启动服务器,它使用相同的命令行参数,创建一个子进程来启动服务器。请注意,所有模块级别的代码都被执行了至少两次。
子进程中 os.environ['BOOTLE_CHILD'] 变量的值被设为 True ,它运行一个不会自动加载的服务器。在代码改变后,主进程会终止掉子进程,并创建一个新的子进程。更改模板文件不会触发自动重载,请使用debug模式来禁用模板缓存。
自动加载需要终止子进程。如果你运行在Windows等不支持 signal.SIGINT (会在Python中raise KeyboardInterrupt 异常)的系统上,会使用 signal.SIGTERM 来杀掉子进程。在子进程被 SIGTERM 杀掉的时候,exit handlers和finally等语句不会被执行。
命令行接口
从0.10版本开始,你可像一个命令行工具那样使用Bottle:
$ python -m bottle
Usage: bottle.py [options] package.module:app
Options: -h, --help show this help message and exit --version show version number. -b ADDRESS, --bind=ADDRESS bind socket to ADDRESS. -s SERVER, --server=SERVER use SERVER as backend. -p PLUGIN, --plugin=PLUGIN install additional plugin/s. -c FILE, --conf=FILE load config values from FILE. -C NAME=VALUE, --param=NAME=VALUE override config values. --debug start server in debug mode. --reload auto-reload on file changes.
ADDRESS 参数接受一个IP地址或IP:端口,其默认为 localhost:8080 。其它参数都很好地自我解释了。
插件和应用都通过一个导入表达式来指定。包含了导入的路径(例如: package.module )和模块命名空间内的一个表达式,两者用”:”分开。下面是一个简单例子,详见 load() 。
# Grab the 'app' object from the 'myapp.controller' module and# start a paste server on port 80 on all interfaces.python -m bottle -server paste -bind 0.0.0.0:80 myapp.controller:app
# Start a self-reloading development server and serve the global# default application. The routes are defined in 'test.py'python -m bottle --debug --reload test
# Install a custom debug plugin with some parameterspython -m bottle --debug --reload --plugin 'utils:DebugPlugin(exc=True)'' test
# Serve an application that is created with 'myapp.controller.make_app()'# on demand.python -m bottle 'myapp.controller:make_app()''
文章来自:开源中国