当前位置: 首页 > 工具软件 > Bottle > 使用案例 >

通过bottle学习python

从智志
2023-12-01

通过bottle学习python

最近发现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)

python装饰器@

参考文档: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’) 执行完再执行

 类似资料: