Flask源码流程剖析

在此之前需要先知道类和方法,个人总结如下:

1.对象是类创建,创建对象时候类的__init__方法自动执行,对象()执行类的 __call__ 方法
 2.类是type创建,创建类时候type的__init__方法自动执行,类() 执行type的 __call__方法(类的__new__方法,类的__init__方法)

# 第0步: 执行type的 __init__ 方法【类是type的对象】
class Foo:
    def __init__(self):
        pass

def __call__(self, *args, **kwargs):
        pass

第1步: 执行type的 __call__ 方法
       1.1  调用 Foo类(是type的对象)的 __new__方法,用于创建对象。
       1.2  调用 Foo类(是type的对象)的 __init__方法,用于对对象初始化。
obj = Foo()
# 第2步:执行Foodef __call__ 方法
obj()

再来我们以下面例子作为参考

from flask import Flask

app = Flask(__name__)

@app.route(‘/‘)
def hello_world():
    return ‘Hello World!‘

if __name__ == ‘__main__‘:
    app.run()

1,首先执行Flask类的__call__方法:

class RequestContext(object):
    def __init__(self,environ):
        self.environ = environ

    def push(self):
        # 3
        # 请求相关数据,加到local中: stack.push...
        _request_ctx_stack.push(self)

        # 获取cookie中的随机字符串,检验是否有,没有就生成
        # 根据随机字符串,获取服务端保存的session的
        # {
        #     ‘xxxxxxx‘: {...}
        #     ‘xxxxxxx‘: {...}
        # }
        # 新用户: {}
        # 老用户:{user:‘xxx‘}
        self.session = self.app.open_session(self.request)
        if self.session is None:
            self.session = self.app.make_null_session()

class Flask:
    def process_response(self, response):
        # 8
        # 执行 after_request装饰器
        for handler in funcs:
            response = handler(response)

        # 将内存中的session持久化到:数据库、....
        if not self.session_interface.is_null_session(ctx.session):
            self.save_session(ctx.session, response)

        return response

    def finalize_request(self, rv, from_error_handler=False):
        # 7
        response = self.make_response(rv)
        try:
            response = self.process_response(response)
            request_finished.send(self, response=response)
        except Exception:
            if not from_error_handler:
                raise
            self.logger.exception(‘Request finalizing failed with an ‘
                                  ‘error while handling an error‘)
        return response

    def full_dispatch_request(self):
        # 5

        # 触发只执行一次的装饰器函数,@before_first_request
        self.try_trigger_before_first_request_functions()
        try:
            # 触发Flask的信号,没用: pip3 install blinker
            request_started.send(self)

            # 执行特殊装饰器:before_request
            # 如果没有返回值,rv=None;有返回值 “嘻嘻嘻”
            rv = self.preprocess_request()
            if rv is None:
                # 触发执行视图函数
                rv = self.dispatch_request()
        except Exception as e:
            rv = self.handle_user_exception(e)

        # 6 对返回值进行封装
        return self.finalize_request(rv)

    def wsgi_app(self, environ, start_response):

        # 处理request,将请求添加到local中
        ctx = self.request_context(environ)
        # 2.处理request和session
        ctx.push()

        error = None
        try:
            try:
                # 4 执行视图函数
                response = self.full_dispatch_request()
            except Exception as e:
                error = e
                response = self.handle_exception(e)
            except:
                error = sys.exc_info()[1]
                raise
            return response(environ, start_response)
        finally:
            if self.should_ignore_error(error):
                error = None
            # 9
            ctx.auto_pop(error)

    def __call__(self, environ, start_response):
        """Shortcut for :attr:`wsgi_app`."""
        return self.wsgi_app(environ, start_response)

原文地址:https://www.cnblogs.com/yifugui/p/8244508.html

时间: 2024-07-31 02:41:41

Flask源码流程剖析的相关文章

11.6 Flask 源码流程,上下文管理

源码流程 创建对象 from flask import Flask """ 1 实例化对象 app """ app = Flask(__name__) """ 2 设置路由 将路由关系放在 app.url_map = {} 中 """ @app.route("/index") def index(): return "index" if —__na

django rest framework之节流的源码流程剖析

视图类: 1 class UserViewset(BaseView): 2 ''' 3 create: 4 创建用户 5 retrieve: 6 7 ''' 8 queryset = User.objects.all() 9 throttle_classes = [UserRateThrottle] #添加节流类 10 authentication_classes = (JSONWebTokenAuthentication, authentication.SessionAuthenticatio

01 flask源码剖析之werkzurg 了解wsgi

目录 01 werkzurg了解wsgi 1. wsgi 2. flask之werkzurg源码流程 3. 总结 01 werkzurg了解wsgi 1. wsgi django和flask内部都没有实现socket,而是wsgi实现. wsgi是web服务网关接口,他是一个协议,实现它的协议的有:wsgiref/werkzurg/uwsgi django之前 from wsgiref.simple_server import make_server def run(environ, start

libevent源码深度剖析二

libevent源码深度剖析二 --Reactor模式 张亮 前面讲到,整个libevent本身就是一个Reactor,因此本节将专门对Reactor模式进行必要的介绍,并列出libevnet中的几个重要组件和Reactor的对应关系,在后面的章节中可能还会提到本节介绍的基本概念. 1 Reactor的事件处理机制 首先来回想一下普通函数调用的机制:程序调用某函数?函数执行,程序等待?函数将结果和控制权返回给程序?程序继续处理. Reactor释义"反应堆",是一种事件驱动机制.和普通

libevent源码深度剖析五

libevent源码深度剖析五--libevent的核心:事件event 张亮 对事件处理流程有了高层的认识后,本节将详细介绍libevent的核心结构event,以及libevent对event的管理. 1 libevent的核心-event Libevent是基于事件驱动(event-driven)的,从名字也可以看到event是整个库的核心.event就是Reactor框架中的事件 处理程序组件:它提供了函数接口,供Reactor在事件发生时调用,以执行相应的事件处理,通常它会绑定一个有效

libevent源码深度剖析七

libevent源码深度剖析七 --事件主循环张亮 现在我们已经初步了解了libevent的Reactor组件--event_base和事件管理框架,接下来就是libevent事件处理的中心部分 --事件主循环,根据系统提供的事件多路分发机制执行事件循环,对已注册的就绪事件,调用注册事件的回调函数来处理事件. 1 阶段性的胜利 Libevent将I/O事件.定时器和信号事件处理很好的结合到了一起,本节也会介绍libevent是如何做到这一点的.     在看完本节的内容后,读者应该会对Libev

libevent源码深度剖析八

libevent源码深度剖析八 --集成信号处理张亮 现在我们已经了解了libevent的基本框架:事件管理框架和事件主循环.上节提到了libevent中I/O事件和Signal以及Timer事件的集成,这一节将分析如何将Signal集成到事件主循环的框架中. 1 集成策略--使用socket pair 前一节已经做了足够多的介绍了,基本方法就是采用"消息机制".在libevent中这是通过socket pair完成的,下面就来详细分析一下.      Socket pair就是一个s

libevent源码深度剖析十二

libevent源码深度剖析十二 --让libevent支持多线程张亮 Libevent本身不是多线程安全的,在多核的时代,如何能充分利用CPU的能力呢,这一节来说说如何在多线程环境中使用libevent,跟源代码并没有太大的关系,纯粹是使用上的技巧. 1 错误使用示例 在多核的CPU上只使用一个线程始终是对不起CPU的处理能力啊,那好吧,那就多创建几个线程,比如下面的简单服务器场景.1 主线程创建工作线程1:2 接着主线程监听在端口上,等待新的连接:3 在线程1中执行event事件循环,等待事

libevent源码深度剖析六

libevent源码深度剖析六 --初见事件处理框架张亮 前面已经对libevent的事件处理框架和event结构体做了描述,现在是时候剖析libevent对事件的详细处理流程了,本节将分析 libevent的事件处理框架event_base和libevent注册.删除事件的具体流程,可结合前一节libevent对event的管理. 1 事件处理框架-event_base 回想Reactor模式的几个基本组件,本节讲解的部分对应于Reactor框架组件.在libevent中,这就表现为event