您的位置 首页 > 腾讯云社区

05 | Tornado源码分析:Configurable---还是牛6504957

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

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

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

# -*- 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的[构造方法]。 ---来自腾讯云社区的---还是牛6504957

关于作者: 瞎采新闻

这里可以显示个人介绍!这里可以显示个人介绍!

热门文章

留言与评论(共有 0 条评论)
   
验证码: