• Flask中'endpoint'(端点)的理解


    翻译整理自Stack Overflowhttp://stackoverflow.com/questions/19261833/what-is-an-endpoint-in-flask
    原文中用到了my_greeting视图函数/端点,我估计是答者笔误,故修改为了give_greeting

    Flask路由是如何工作的

    整个flask框架(及以Werkzeug类库为基础构建的应用)的程序理念是把URL地址映射到你想要运行的业务逻辑上(最典型的就是视图函数),例如:

    @app.route('/greeting/<name>')
    def give_greeting(name):
        return 'Hello, {0}!'.format(name)
    • 1
    • 2
    • 3

    注意,add_url_rule函数实现了同样的目的,只不过没有使用装饰器,因此,下面的程序是等价的:

    # 抬头没有使用路由装饰器,我们在最后用另一种方法添加路由.
    def give_greeting(name):
        return 'Hello, {0}!'.format(name)
    
    app.add_url_rule('/greeting/<name>', 'give_greeting', give_greeting)
    • 1
    • 2
    • 3
    • 4
    • 5

    备注:add_url_rule()中3个参数依次是ruleview_funcendpoint.

    假设www.example.org站点定义了以上视图,用户在浏览器中输入以下地址

    http://www.example.org/greeting/Mark
    • 1

    Flask的工作就是捕捉这个URL地址,弄清用户想要做什么,并在众多的Python函数中匹配一个可以处理它的函数,回到我们的实例中,URL地址就是

    /greeting/Mark
    • 1

    拿着这个地址到路由表中做匹配,flask发现这个地址指向了give_greeting函数。
    然而,当我们用这种最常用的方法创建视图时,flask却向我们隐藏了一些其他的细节信息。在这个场景中,flask并没有直接从URL地址跳转到应该响应它请求的视图函数上:

    URL (http://www.example.org/greeting/Mark) 被视图函数处理 ("give_greeting"函数)
    • 1

    事实上,这里还有另一个步骤–把URL地址映射到端点上(URL**–>endpoint–>**viewfunction):

    URL (http://www.example.org/greeting/Mark) 映射到端点"give_greeting"上.
    指向端点"give_greeting"的请求被视图函数"give_greeting"处理.
    • 1
    • 2

    从根本上来说,端点就是程序中一组逻辑处理单元的ID,该ID对应的代码决定了对此ID请求应该作出何种响应。通常,端点与视图函数同名,但是你也可以修改它,例如:

    @app.route('/greeting/<name>', endpoint='say_hello')
    def give_greeting(name):
        return 'Hello, {0}!'.format(name)
    • 1
    • 2
    • 3

    现在就成了这样:

    URL (http://www.example.org/greeting/Mark) 映射到端点"say_hello"上.
    指向端点"say_hello"的请求被视图函数"give_greeting"处理.
    • 1
    • 2

    Endpoint有什么作用

    端点通常用作反向查询URL地址(viewfunction**–>endpoint–>**URL)。例如,在flask中有个视图,你想把它关联到另一个视图上(或从站点的一处连接到另一处)。不用去千辛万苦的写它对应的URL地址,直接使用URL_for()就可以啦:

    @app.route('/')
    def index():
        print url_for('give_greeting', name='Mark') # 打印出 '/greeting/Mark'
    
    @app.route('/greeting/<name>')
    def give_greeting(name):
        return 'Hello, {0}!'.format(name)
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    备注:url_for()give_greeting是端点名.

    这样做是大有裨益的:我们可以随意改变应用中的URL地址,却不用修改与之关联的资源的代码。

    为何要多此一举

    那么问题来了:为何要多此一举,为何要先把URL映射到端点上,再通过端点映射到视图函数上,为何不跳过中间的这个步骤?
    原因就是采用这种方法能够使程序更高、更快、更强。例如蓝本。蓝本允许我们把应用分割为一个个小的部分,现在admin蓝本中含有超级管理员级的资源,user蓝本中则含有用户一级的资源。
    蓝本允许咱们把应用分割为一个个以命名空间区分的小部分:
    main.py:

    from flask import Flask, Blueprint
    from admin import admin
    from user import user
    
    app = Flask(__name__)
    app.register_blueprint(admin, url_prefix='admin')
    app.register_blueprint(user, url_prefix='user')
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    admin.py:

    admin = Blueprint('admin', __name__)
    
    @admin.route('/greeting')
    def greeting():
        return 'Hello, administrative user!'
    • 1
    • 2
    • 3
    • 4
    • 5

    user.py:

    user = Blueprint('user', __name__)
    @user.route('/greeting')
    def greeting():
        return 'Hello, lowly normal user!'
    • 1
    • 2
    • 3
    • 4

    注意,在两个蓝本中路由地址‘/greeting’的函数都叫"greeting"。如果我想调用admin对应的greeting函数,我不能说“我想要greeting”,因为这里还有一个user对应的greeting函数。端点这时就发挥作用了:指定一个蓝本名称作为端点的一部分–通过这种方式端点实现了对命名空间的支持。所以,我们可以这样写:

    print url_for('admin.greeting') # Prints '/admin/greeting'
    print url_for('user.greeting') # Prints '/user/greeting'
    • 1
    • 2

    来发实例

    from flask import Flask, url_for
    
    app = Flask(__name__)
    
    # We can use url_for('foo_view') for reverse-lookups in templates or view functions
    @app.route('/foo')
    def foo_view():
        pass
    
    # We now specify the custom endpoint named 'bufar'. url_for('bar_view') will fail!
    @app.route('/bar', endpoint='bufar')
    def bar_view():
        pass
    
    with app.test_request_context('/'):
        print (url_for('foo_view'))  #/foo
        print (url_for('bufar'))  #/bar
        # url_for('bar_view') will raise werkzeug.routing.BuildError
        print (url_for('bar_view'))  #端点bar_view是没有定义的
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    程序运行结果
    python_endpoint_程序运行结果

    更多参考:
    http://www.cnblogs.com/eric-nirnava/p/endpoint.html

  • 相关阅读:
    随时积累随手记(持续更新...)
    Zookeeper集群搭建
    Dubbo——基于Zookeeper服务框架搭建及案例演示
    nginx配置浅析
    阿里面试回来,想和Java程序员谈一谈
    博客收藏列表
    启示录:打造用户喜爱的产品
    js深拷贝和浅拷贝
    MyBatis 总结记录
    ActiveMQ初体验
  • 原文地址:https://www.cnblogs.com/yanzi-meng/p/8136321.html
Copyright © 2020-2023  润新知