zoukankan      html  css  js  c++  java
  • Flask即插视图与tornado比较

    由于公司使用了Tornado框架和Flask框架,之前一直使用的都是Flask框架,已经对url下面紧跟着视图的写法很固执。刚开始接触Tornado框架,对于其url和视图分开的写法思想上无法转变。今天看了Flask的源码和相关教程看到原来 Flask也可以写出和Tornado类似的代码结构--Flask即插视图。

    代码如下:

    from functools import wraps
    
    from flask import Flask, request
    from flask.views import MethodView
    
    app = Flask(__name__)
    
    
    # get请求装饰器
    def decorator_func_get(f):
        @wraps(f)
        def write(*args, **kwargs):
            print(request.method, 'decorator_func_get')
            print('You can add some decorator before request into view function!')
            return f(*args, **kwargs)
    
        return write
    
    
    # post请求装饰器
    def decorator_func_post(f):
        @wraps(f)
        def write(*args, **kwargs):
            print(request.method, 'decorator_func_post')
            print('You can add some decorator before request into view function!')
            return f(*args, **kwargs)
    
        return write
    
    
    # 公用装饰器
    def decorator_func_all(f):
        @wraps(f)
        def write(*args, **kwargs):
            print(request.method, 'decorator_func_all')
            print('You can add some decorator before request into view function!')
            return f(*args, **kwargs)
    
        return write
    
    
    class User(MethodView):
        # 所以http方法进入后都要使用的装饰器
        decorators = [decorator_func_all]
    
        # 只针对get请求的装饰器
        @decorator_func_get
        def get(self, user_id):
            return f'get uid:{user_id}'
    
        # 只针对post请求的装饰器
        @decorator_func_post
        def post(self):
            uid = request.form.get('user_id')
            return f'create a user {uid}'
    
        def delete(self, user_id):
            return f'delete a uid:{user_id}'
    
        def put(self, user_id):
            return f'update a uid:{user_id}'
    
    
    # 可以重构一个路由注册函数,可以更加方便
    user_view = User.as_view('user_api')  # 'user_api'为endpoint
    app.add_url_rule('/users', defaults={'user_id': None}, view_func=user_view, methods=['GET'])  # url:/users,GET
    app.add_url_rule('/users', view_func=user_view, methods=['POST'])  # url:users,POST
    app.add_url_rule('/users/<int:user_id>', view_func=user_view, methods=['GET', 'PUT', 'DELETE'])  # url:users,POST
    
    app.run(host='127.0.0.1', port=8000, debug=True)

    其实对于即插视图的add_url_rule()方法和如下的route()方法都是一样的,因为源码中,route()调用的就是add_url_rule()方法。

    代码段:1

    @app.route('/', methods=['GET', 'POST'])
    @some_decorator
    def index(): data = { 'msg': 'API SERVER IS RUNNING~', 'version': version, } data.update(get_version_ctrl()) return msg(data)

    即插视图优点:

    • 可以更好的理解tornado框架的大致框架结构。
    • 写出更容易符合RestFul风格的代码,因为对于资源的增删改查,通过get,post等方法对应到相关的类方法上。
    • 不用像 代码段:1 中那样,在GET,POST都存在时,使用 
      if request.method=='GET':
          print('do some get method things')
      else:
          print('do some other method things')

      如此费事恶心的代码

    • 解耦代码,不用像  代码段:1  中那样装饰器只能对整个视图函数使用,无法具体到对应的不同的请求方法上。
    • 路由集中管理

    Tornado框架简单程序(主要体现其注册视图函数的方法和flask的即插视图很像):

    import torndb  
    import tornado.web  
    import tornado.ioloop  
    from tornado.options import define,options,parse_command_line  
      
    define('port',default=8888,help='run on the port',type=int)  
    database=torndb.Connection('localhost','talk',user='root',password='ll')  
    l=[]  
    class MainHandler(tornado.web.RequestHandler):  
        def get(self):  
            self.render('a.html',title='haha',items=l)  
        def post(self):  
            count=1  
            print(self.request.remote_ip)  
            talk=self.get_argument('talk')  
            talk=str(talk)  
            database.execute('insert into chatting(id,content) values(%d,"%s")'%(count,talk))  
            l.append(talk)  
            self.render('a.html',title='haha',items=l)  
    def main():  
        parse_command_line()  
        app=tornado.web.Application(  
                [  
                    (r'/',MainHandler),  
                    ],  
                )  
      
        app.listen(options.port)  
        tornado.ioloop.IOLoop.instance().start()  
          
    if __name__=='__main__':  
        main()

    相关教程:http://docs.jinkan.org/docs/flask/views.html

  • 相关阅读:
    建造者模式的使用场景
    由于losf引起的pxc启动报错处理
    mysql5.6源码自动安装脚本
    mysql5.7.16二进制安装
    Maven入门
    数据链路层
    图-拓扑排序
    线性表-队列
    线性表-链表
    Java基本概念(未完)
  • 原文地址:https://www.cnblogs.com/rgcLOVEyaya/p/RGC_LOVE_YAYA_830days.html
Copyright © 2011-2022 走看看