你应该会玩 Flask我爱编程

如何理解 flask 中的 Blueprint 的 name 参

2018-04-16  本文已影响55人  藕丝空间

我一直以为 Blueprint 中的 name 参数和 url_for 中所用到的 endpoint (端点)有关,下面是我为什么这样理解的。

1、问题

通常我们在 flask 项目中使用蓝图的时候是这样定义蓝图的:

admin = Blueprint('666', __name__)

其中,第一个参数究竟有什么作用?能否随便命名,或者干脆不命名??

答案是 否定的!!!

2、解惑

首先,我们看一下 flask 的源码: https://github.com/pallets/flask/blob/master/flask/blueprints.py
其中,有下面的代码:

class Blueprint(_PackageBoundObject):
    ...
    ...
    def __init__(self, name, import_name, static_folder=None,
                 static_url_path=None, template_folder=None,
                 url_prefix=None, subdomain=None, url_defaults=None,
                 root_path=None):
        _PackageBoundObject.__init__(self, import_name, template_folder,
                                     root_path=root_path)
        self.name = name
        self.url_prefix = url_prefix
        self.subdomain = subdomain
        self.static_folder = static_folder
        self.static_url_path = static_url_path
        self.deferred_functions = []
        if url_defaults is None:
            url_defaults = {}
        self.url_values_defaults = url_defaults

上面的代码可以明显的看到, Blueprint 类继承与 _PackageBoundObject,其中,name 参数,可是该类自己定义的,不是继承的,那么,我们继续在源码中查找 name 参数的作用。

在该类中寻找 self.name, 我们可以看到另外 8 处内容, 分别在该类的 before_request、afte\r_request、teardown_request、context_processor、url_value_preprocessor、url_defaults、errorhandler、register_error_handle 这 8 个类函数中,基本上函数中用到的地方都是:

 self.record_once(lambda s: s.app.before_request_funcs
            .setdefault(self.name, []).append(f))

那么,我们再看看这个 record_once 函数的作用,该函数也是在该类中定义的

    def record_once(self, func):
        """Works like :meth:`record` but wraps the function in another
        function that will ensure the function is only called once.  If the
        blueprint is registered a second time on the application, the
        function passed is not called.
        """
        def wrapper(state):
            if state.first_registration:
                func(state)
        return self.record(update_wrapper(wrapper, func))

通过注释,很明显地看到这个函数的作用是为了将 name 参数作为唯一标识,在程序上下文中区分蓝图所用的。

那么,回到原来的问题。

一、之所以可以随便定义名称,感觉没有什么影响,那是错觉。

二、建议大家试试如果不定义 name 参数,程序会不会报错。结果是必定报错,因为这个参数是必须的。

上一篇 下一篇

猜你喜欢

热点阅读