前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >05 | Tornado源码分析:Configurable

05 | Tornado源码分析:Configurable

作者头像
python编程从入门到实践
发布2020-05-28 00:01:21
7580
发布2020-05-28 00:01:21
举报

hello,各位好,好久没有更新,一直在整理Tornado 底层源码,力求用最少的代码来为大家讲解清楚其底层的运行原理。看到标题是否想到今天会分享什么呢? 先从一张图中看一下tornado 各个部件 的位置:

不知大家是否记得上次我们讲过的代码,其中一个片段是这样的: tornado.ioloop.IOLoop.instance().start() 我们今天就从这句开始分析,从图上我们也能看到 IOLoop是最底层的,这个是做什么的呢?这个是一个“大循环”,是事件循环的核心代码。单击进入我们先大概看一下长什么样子的:

从图片可以看出,这个IOLoop类是继承了 Configurable 这个类。为何要继承这个类?能为IOLoop做什么呢? 我们看一下代码:[注意:我贴出的代码是我删减过后的代码,只为给大家说清楚其主要逻辑和设计思路] 先整体看一下涉及到的主要函数内容:

代码语言:javascript
复制
# -*- encoding: utf-8 -*-
# !/usr/bin/python
"""
@File    : configure_core.py
@Time    : 2020/5/23 18:10
@Author  : haishiniu
@Software: PyCharm
"""
from tornado.util import unicode_type, import_object

class Configurable(object):
    __impl_class = None  # type: type
    __impl_kwargs = None  # type: Dict[str, Any]

    def __new__(cls, *args, **kwargs):
        base = cls.configurable_base()  # 返回子类的配置基类 -->IOLoop
        init_kwargs = {}

        # 如果子类的配置基类就是子类本身,那么:
        # 如果配置基类通过__impl_class 属性指定了实现类,则使用它;
        # 否则,使用子类的 configurable_default() 方法返回的实现类。
        if cls is base:
            impl = cls.configured_class()  # 具体实现类[底层的IO多路复用机制]EPollIOLoop
            if base.__impl_kwargs:
                init_kwargs.update(base.__impl_kwargs)

        # 如果子类的配置基类不是自身,直接使用子类作为实现类。
        else:
            impl = cls
        init_kwargs.update(kwargs)

        # 创建实现类的实例
        instance = super(Configurable, cls).__new__(impl)

        # 使用传递给构造方法的参数,调用实例的initialize方法,进行初始化。
        # 实例的__init__方法也会被自动调用,但是一般不应该使用__init__方法进行初始化,而是建议使用initialize方法
        instance.initialize(*args, **init_kwargs)  # EPollIOLoop(initialize)  --> PollIOLoop(initialize)  --> IOLoop --> Configurable
        return instance

    # configurable_base() 方法用于 返回子类的配置基类。通常,子类的配置基类就是其自身(但是不是必须)。
    # issubclass(子类, 配置基类) == True。
    # 该方法需要在子类中实现。
    @classmethod
    def configurable_base(cls):
        # type: () -> Any
        raise NotImplementedError()

    # configured_class()方法的作用是:
    # 如果子类的__impl_class属性是None(也就是,其配置基类没有通过__impl_class属性指定实现类),
    # 那么,则使用它的 configurable_default() 方法返回的类作为实现类,并将其保存到配置基类的__impl_class属性中;
    # 否则,直接使用配置基类的__impl_class属性指定的实现类。
    # 实现类是子类自身或其子类。
    @classmethod
    def configured_class(cls):
        # type: () -> type
        base = cls.configurable_base()  # 返回子类的配置基类 -->IOLoop
        if cls.__impl_class is None:
            base.__impl_class = cls.configurable_default()  # 具体实现类[底层的IO多路复用机制]EPollIOLoop
        return base.__impl_class

    # configure()方法用于在 运行时,为 Configurable的子类指定实现类,以及初始化时使用的参数。
    # 它们会被保存到 子类的配置基类的 __impl_class 和 __impl_kwargs属性中
    @classmethod
    def configure(cls, impl, **kwargs):
        # type: (Any, **Any) -> None
        base = cls.configurable_base()  # 返回子类的配置基类 -->IOLoop
        if isinstance(impl, (str, unicode_type)):
            impl = import_object(impl)
        if impl is not None and not issubclass(impl, cls):
            raise ValueError("Invalid subclass of %s" % cls)

        base.__impl_class = impl
        base.__impl_kwargs = kwargs

# 简单总结:
# 继承 Configurable 的子类,需要实现下列的方法:
    # 1.configurable_base(cls):通常返回子类自身
    # 2.configurable_default(cls):返回默认的实现类,比如根据不同的操作系统平台,返回不同的实现类

# 子类的实现类,需要实现:
# initialize(self, *a, **kw):用于实例的初始化

# Configurable的核心是其构造方法:__new__。它是 其实现子类的 [工厂方法]。
# 在新式类中,如果子类没有定义__new__方法,那么会使用父类的该方法,来创建对象。
# 因此,Configurable的 未定义__new__方法的子类(比如IOLoop等) 都会使用Configurable的[构造方法]。
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-05-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 python编程从入门到实践 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档