最近发现bottle–web框架,非常小,只有一个文件,可以直接拖进项目里用,也方便调试,产生了通过bottle学习python的一些概念的想法
from bottle import Bottle, run
app = Bottle()
@app.route('/hello')
def hello():
return "Hello World!"
run(app, host='localhost', port=8080)
参考文档:https://zhuanlan.zhihu.com/p/160979609
装饰器基本上就是调用一个函数,入参为另一个函数。
web框架在实现路由的时候基本都会提供装饰器方便使用,如示例的@app.route('/hello')
源码如下:
class Bottle:
...
def route(self,
path=None,
method='GET',
callback=None,
name=None,
apply=None,
skip=None, **config):
""" A decorator to bind a function to a request URL. Example::
@app.route('/hello/<name>')
def hello(name):
return 'Hello %s' % name
The ``<name>`` part is a wildcard. See :class:`Router` for syntax
details.
:param path: Request path or a list of paths to listen to. If no
path is specified, it is automatically generated from the
signature of the function.
:param method: HTTP method (`GET`, `POST`, `PUT`, ...) or a list of
methods to listen to. (default: `GET`)
:param callback: An optional shortcut to avoid the decorator
syntax. ``route(..., callback=func)`` equals ``route(...)(func)``
:param name: The name for this route. (default: None)
:param apply: A decorator or plugin or a list of plugins. These are
applied to the route callback in addition to installed plugins.
:param skip: A list of plugins, plugin classes or names. Matching
plugins are not installed to this route. ``True`` skips all.
Any additional keyword arguments are stored as route-specific
configuration and passed to plugins (see :meth:`Plugin.apply`).
"""
if callable(path): path, callback = None, path
plugins = makelist(apply)
skiplist = makelist(skip)
def decorator(callback):
if isinstance(callback, basestring): callback = load(callback)
for rule in makelist(path) or yieldroutes(callback):
for verb in makelist(method):
verb = verb.upper()
route = Route(self, rule, verb, callback,
name=name,
plugins=plugins,
skiplist=skiplist, **config)
self.add_route(route)
return callback
return decorator(callback) if callback else decorator
示例代码等价于
from bottle import Bottle, run
app = Bottle()
app_route = app.route('/hello')
# 此时app_route 是函数decorator
@app_route # 这个时候才会将hello函数作为值,调用函数decorator
def hello():
return "Hello World!"
run(app, host='localhost', port=8080)
以下个人理解,仅供参考
将装饰器细分为两种,暂定为:真装饰器,表装饰器
上处代码的@app_route是真装饰器,只有一个入参,就是被其修饰的函数
而@app.route(‘/hello’)是表装饰器,代码关系类似 @(app.route(‘/hello’)) ,会先进行一些操作(例如上例就对path之类的处理了下),返回一个真装饰器,再进入真装饰器的流程
用类似操作符号的优先级好像更好解释,@app.route(‘/hello’), @ 优先级最低,等app.route(‘/hello’) 执行完再执行