zoukankan      html  css  js  c++  java
  • 西二Python第六轮

    运用werkzeug自建框架

    一.自建框架信息

    1.实现的功能

    功能类型 代表名称
    程序接受、响应信息以及运行 app.run()
    路由以及视图函数处理 app.way('/',methods=['GET'])
    请求处理 request
    全局变量 g
    会话 session
    模板以及渲染模板 template
    静态文件以及返回静态文件 static
    全局current_app current_app

    2.运用的原理函数

    原理库 函数
    werkzeug.serving run_simple
    werkzeug.wrappers Request,Response
    werkzeug.routing Map,Rule
    werkzeug.utils redirect
    werkzeug.wsgi SharedDataMiddleware
    jinja2 Environment,FileSystemLoader
    itsdangerous TimedJSONWebSignatureSerializer
    werkzeug.local LocalProxy,LocalStack
    os /

    二、功能介绍

    1.程序接受、响应信息以及运行

    在Freedom类中定义程序运行函数fly(),fly()使用run_simple函数进行接口设置,之后每次与服务器的交互都会调用wsgi_app函数,然后会调用下列两个主要函数最后返回响应
    wsgi_app->dispatch_request->make_response->Response

    wsgi_app函数将服务器传输的environ信息封装到Request、Response中,进行和request相关的工作后调用dispatch_request

    dispatch_request函数主要进行查找请求中对应的路由信息并调用路由函数,将返回值再输入make_response函数中进行简单处理以及建立session到响应中,再返回处理后的响应

    2.路由以及视图函数处理

    在Freedom类__init__中调用Map实例化url_map用于储存路由Rule中的相关信息,再建立初始化一个字典view_functions用于存储函数名与函数的对应关系。

    Freedom类中注册路由的函数是register_url需要路由、该路由下函数名、该路由下函数、访问方法参数,register_url中实例化了Rule并将实例加入到url_map中,将函数名与函数对应传入到view_functions,调用register_url就可以创建路由。

    我模仿flask也在register_url函数上加上了一个装饰器,装饰器名为way接受路由以及方法作为参数,在way中默认方法为GET,之后会传入函数作为参数调用decorator函数,decorator函数再调用register_url注册路由后返回被输入的函数。

    最后提供给用户的视图函数等的形式就是下面这个样子

    当与服务器交互时,调用dispatch_request函数从request中提取出请求的路由信息,再从view_functions中得到视图函数、执行视图函数,其中make_response函数是把视图函数的返回值按照分类封装到Response中返回响应,使得用户不用每次都要调用Response,再把响应返回给服务器,这就是我做的简单路由过程。

    2.请求处理、全局变量、会话、全局current_app

    对这四个的处理在ctx模块和globals模块中,ctx模块中主要分为AppContext类和RequestContext类两个部分,globals模块中调用了LocalProxy,LocalStack支持多线程以及队列操作。在ctx中RequestContext设置了request以及session的内容,AppContext设置了current_app以及g的内容
    (1)globals模块
    在globals模块中设置了两个栈request_stack、app_stack,然后分别从app_stack和request_stack类中提取出current_app、g以及request、session,在RequestContext的push中已经将对应的RequestContext和AppContext推入栈中,在golobals中提取提取信息函数如下方request方法:

    分别将信息提取,将会给每个信息加上LocalProxy进行代理(看的意思似乎是为了不同线程保持独立),这样就可以从gobals中调用四个信息,进行相关的操作了。

    (2)ctx模块
    RequestContext
    RequestContext中包括了request、session的内容,有push和pop方法,在RequestContext的__init__中初始化request将服务器传入的environ信息封装,引入Freedom的实例,再初始化url_adapter和session

    在push中将request_stack、app_stack栈顶的信息更换进行信息的更新,并在此时创建session

    在push中的session创建我采用了itsdangerous中的TimedJSONWebSignatureSerializer将__init__中初始化的session字典转换成token,push中的create_session函数从引入的app中调用search_session函数从栈顶的request的cookies中得到session编码后的token,编码session的函数是RequestContext的set_token函数,这个函数在Freedom类的dispatch_request函数中被调用并通过response的set_cookies将token建立在cookies中,这样就实现了session。


    AppContext
    AppContext用RequestContext差不多,先在__init__中初始化g以及引入app,然后AppContext中同样也有push以及pop方法,但AppContext还没有完善只有很少的功能

    3.模板以及渲染模板

    最初的模板在Freedom的__init__中初始化为文件夹tamplates,模板的设置我从jinja2中调用Environment,FileSystemLoader并jinja_env设置为文件夹tamplates的地址,这样就实现了默认的模板查询地址和存储地址,在Freedom中我设置了一个由用户自定义模板地址的函数set_templates,这个函数需要输入文件夹名作为参数

    在Freedom中我也设置了一个渲染模板的函数drawing_template,这个函数从jinja_env中获取模板文件并渲染返回

    4.静态文件以及返回静态文件

    关于静态文件的地址我再Freedom中建立了一个set_static函数,这个函数在__init__中会被调用并且初始化app_path文件保存地址,默认是static文件夹,用户可以通过这个函数设置提取和设置保存文件的文件夹。在这个函数中我设置了有一个提取文件的路由,之后通过SharedDataMiddleware设置返回静态文件。

    5.遇到的问题

    在ctx的全局变量g,初始化时我将g初始化为一个空类的实例,但是仍然能实现全局变量的功能

  • 相关阅读:
    Mysql 从库的备份中恢复一张表
    my.cnf 配置文件参数解释
    利用mvn deploy命令上传包(转)
    IntelliJ IDEA 项目文件旁边都有0%classes,0% lines covered
    idea启动java Maven项目,出现" java: 程序包xxxx不存在"
    org/apache/poi/POIXMLTypeLoader或者java.lang.NoSuchFieldError: RETURN_NULL_AND_BLANK
    elasticsearch,kibana,logstash.下载
    idea显示 RunDashboard ,多个启动项时列表显示
    写for循环快捷生成方式
    Could not transfer artifact xxx from/to xxx解决方案
  • 原文地址:https://www.cnblogs.com/trainking-star/p/12986597.html
Copyright © 2011-2022 走看看