大家好,欢迎来到IT知识分享网。
我一直以为 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 参数设置成一样的,你试试程序会不会报错。
- 第二个原因,没有用到 url_for 函数,这个函数中会用到蓝图的 name 参数,或者我们直接这样简化的调用 url_for(‘.index’) 函数, 那个 ‘.’ 代表了当前的蓝图。
- 还是回到 url_for 函数,如果在 html 的 jinja2 中调用,得这样写 url_for(‘name.index’),其中的 name 就是蓝图的 name 参数。
二、建议大家试试如果不定义 name 参数,程序会不会报错。结果是必定报错,因为这个参数是必须的。
- 在 view 视图中,我们使用 装饰器 的写法,一般是把函数名称当做 endpoint 的,如果你在两个不同的蓝图中,使用同一个名称来定义视图函数,那么 endpoint 按照默认方案就无法是 唯一标识 了,必须得加上蓝图的名称,所以蓝图的名称也得是唯一的。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/39127.html