• [python] pprika:基于werkzeug编写的web框架(5) ——蓝图blueprint


    蓝图实例

    from pprika import Blueprint
    
    main = Blueprint('main', '/animals')
    
    
    @main.route('/cat')
    def get_meow():
        return '喵喵!!是猫咪'

    蓝图的初始化需要提供至少一个参数

    class Blueprint(object):
        def __init__(self, name, url_prefix=None):
            if url_prefix is None:
                url_prefix = '/' + name
            self.name = name
            self.url_prefix = url_prefix
            self._deferred_funcs = []

    name为该蓝图的名称,是之后路由时的依据,需要每个蓝图都不一样。而url_prefix默认为name,它用于附加到path之前,划分不同蓝图的作用域?如上例所对应的请求url则为 http://xy.z/animals/cat。_deferred_funcs 的用途后面会提到。

    蓝图的路由及请求处理几乎与PPrika类一致,如上述route注册方式等同于 main.add_url_rule('/cat', 'get_meow', get_meow) ,因此直接讲add_url_rule。

    add_url_rule

        def add_url_rule(self, path, endpoint=None, view_func=None, **options):
            path = "/".join((self.url_prefix.rstrip("/"), path.lstrip("/")))
    
            if view_func and hasattr(view_func, "__name__"):
                assert (
                    "." not in view_func.__name__
                ), '视图函数名不应带"."'
    
            if endpoint:
                assert "." not in endpoint, 'endpoint参数不可带"."'
            if endpoint is None:
                assert view_func is not None, "无endpoint时view_func不可为空"
                endpoint = view_func.__name__
    
            endpoint = f'{self.name}.{endpoint}'

    上面这一大段其实只做了三件事:附加 url_prefix 到path前、确保视图函数名不能带点(dot)、将endpoint调整为 name.xx 的点分结构。因为blueprint的路由请求响应本质还是通过app进行的,它只是提供了代码更好的组织方式(还有相对独立的错误处理),所以只要处理好参数转发给app即可。 ↓

            # 函数通过deferred_funcs转发,等到有了app再执行(注册rule)
            self._deferred_funcs.append(
                lambda a: a.add_url_rule(path, endpoint, view_func, **options)
            )

    最后用之前处理好的参数调用PPrika类的同名方法即可,但由于此时app未必存在,因此需要通过 self._deferred_funcs 先将该操作保存起来,等后面把blueprint注册到app上时再调用。

    同样的,blueprint上的error_handler等也是这样,最终都将注册操作暂存到_deferred_funcs 上,等app出现再转发给它,这里不多赘述。

    register

        def register(self, app):
            for f in self._deferred_funcs:
                f(app)

    比起flask,pprika的蓝图注册就只是调用之前暂存的那些lambda函数,省去了static、template等不少处理,而且由于省去了flask.BlueprintSetupState这一中间层,url_prefix在蓝图对象实例化后就不可再变。

    而这个register函数又由PPrika.register_blueprint调用↓

    PPrika.register_blueprint

        def register_blueprint(self, blueprint):
            bp_name = blueprint.name
            if bp_name in self.blueprints:
                assert blueprint is self.blueprints[bp_name], f"""
                    已存在名为 {bp_name} 的blueprints:{self.blueprints[bp_name]},
                    请确保正在创建的 {blueprint} 名称唯一
                """
            else:
                self.blueprints[bp_name] = blueprint
            blueprint.register(self)

    做了两件事:根据app.blueprints保存的蓝图名与蓝图对象映射确保每个蓝图名称都唯一,在此基础上将这次注册的蓝图记入app.blueprints并调用蓝图上的register完成后续注册过程。

    这样一个蓝图对象就成功注册到app上了,之后蓝图上的请求、错误实质都会用app上之前介绍的那些函数处理,与一般app注册的视图没什么差别。

    结语

    本篇的blueprint.Blueprint是之后restful.Api实现的基础,可以说Api就是一个增强的Blueprint

    之后预计由两篇讲述restful功能的实现

    [python] pprika:基于werkzeug编写的web框架(6) ——restful的错误处理

  • 相关阅读:
    将博客搬至CSDN
    小啃机器学习(1)-----ID3和C4.5决策树
    然爸读书笔记(2014-12)----20个月赚130亿
    然爸读书笔记(2014-11)----小米的尖叫
    然爸读书笔记(2014-10)----Bootsrap用户手册
    然爸读书笔记(2014-9)----互联网思维到底是什么
    然爸读书笔记(2014-8)----结果第一
    论文阅读(2014-2)----The YouTube Video Recommendation System
    然爸读书笔记(2014-7)----平台战略
    扎克伯格谈Facebook创业过程
  • 原文地址:https://www.cnblogs.com/Stareven233/p/12977063.html
Copyright © 2020-2023  润新知