第8.8节 Python使用__new__方法和构造方法__init__完成类实例化的过程详解

前面章节介绍了Python类中的__new__方法和构造方法__init__,并通过实例分析了二者之间关系,本节系统化的总结一下Python中类实例化过程。具体步骤如下:

一、 开发者通过对象构造器表达式“实例对象=类(参数列表)”启动创建新的实例的任务;

二、 Python查找类的__new__方法

Python首先在准备实例化的类中找new__方法,如果对应类没有__new__方法则从直接父类中查找,如果从直接父类中查找也没有,再找直接父类的直接父类,依此类推,一直到查到一个__new__方法为止(如果自定义类没有,则会找到所有类的父类object类的__new__方法)。

三、 Python传递参数给类的__new__方法

Python找到类对应的__ new__方法后,将对象构造器表达式中的类以及参数列表传给查找到的__new__方法(如果是object类的__new__方法,是否只传自定义类的类名还是参数都传参老猿尚未确认)作为参数,并执行该方法的代码;

  1. __new__方法在应用通过对象构造器表达式触发时至少要有一个参数cls,代表要实例化的类对象,此参数在实例化时由Python解释器自动提供;
  2. 常规情况下,__new__方法执行时,除了object类的__new__方法,所有类中重写的__new__方法都必须调用其父类的__new__方法,并在调用时将本方法中的第一个实参cls传给父类的__new__方法作为第一个参数;
  3. 自定义类的__new__方法调用传入的cls,除了逐层传入外,也可以进行调整,在某些情况下,根据应用需要可以将cls参数对应实参修改为其他类;
  4. 在上述调用层级中,object类的__new__方法一定是最后调用的一个;
  5. 每个自定义类的__new__()方法不能在该方法内调用自身的__new__()来制造实例,必须调用父类的方法,否则会造成死循环。

    四、 __new__方法返回实例对象

    object类的__new__最先返回一个参数cls对应的实例给调用其的自定义子类,自定义子类__new__方法根据情况继续返回给其调用子类的__new__方法,直到返回给对象构造器表达式的调用方。

    所有父类执行__new__方法后必须向子类返回一个实例对象,该实例对象常规情况下是__new__方法第一个参数cls对应的“类”实例,子类再将该实例返回给其调用者,直到传递回给最开始的调用者即“对象构造器表达式”对应的应用;
  6. 由于自定义类的__new__方法调用传入的cls可以修改,上层自定义类的__new__方法也可以改变返回值的值和类型,因此有可能返回的实例不一定是“对象构造器表达式”对应的“类”;
  7. 使用__new__()方法改变返回的实例类型主要是为了允许不可变类型(如int, str, tuple)的子类定制实例,还有就是实现自定义的metaclass。关于metaclass(元类)的内容老猿还没深入研究,暂不介绍。

五、 Python判断__new__方法返回实例对象是否是对象构造器表达式中”类”cls的实例,如果不是则不会调用任何类的构造方法(即使是父类的实例也不行),直接将实例返回给对象构造器表达式的调用方,否则转下步;

  1. 关于这点,老猿验证了几种情况是都不会执行任何类的构造方法,但在网上一些资料查阅的情况,有说可以执行返回实例对应类的构造方法的,老猿没有碰到这种情况,但也许真有这种情况,或许需要特定条件才会触发,因此将这个疑点在此记录下来。

    六、 __new__方法执行完成后,如果返回的实例是cls类的实例,则将此实例作为self传递给构造方法,并将__new__方法中除cls外的参数也传给构造方法;

    七、 执行构造方法,构造方法执行后将实例返回给在对象构造器表达式左侧的”实例对象”,完成整个类的实例化过程。

老猿Python系列文章用于逐步介绍老猿学习Python后总结的学习经验,这些经验有助于没有接触过Python的程序员可以很容易地进入Python的世界。

欢迎大家批评指正,谢谢大家关注!

第8.8节 Python使用__new__方法和构造方法__init__完成类实例化的过程详解的更多相关文章

  1. 第8.5节 Python类中的__new__方法和构造方法__init__关系深入剖析:执行顺序及参数关系案例详解

    上节介绍了__new__()方法这个比构造方法还重要的方法的语法,本节通过案例来详细剖析__new__()方法的细节以及它与构造方法之间的关系. 一.    案例说明 本节以圆Cir类为例来说明,为了 ...

  2. [Python] Python 之 __new__() 方法与实例化

    __new__() 是在新式类中新出现的方法,它作用在构造方法建造实例之前,可以这么理解,在 Python 中存在于类里面的构造方法 __init__() 负责将类的实例化,而在 __init__() ...

  3. Python 之 __new__() 方法与实例化

    原文链接:https://www.cnblogs.com/ifantastic/p/3175735.html __new__() 是在新式类中新出现的方法,它作用在构造方法建造实例之前,可以这么理解, ...

  4. Python 之 __new__() 方法与实例化(转)

    _new__() 是在新式类中新出现的方法,它作用在构造方法建造实例之前,可以这么理解,在 Python 中存在于类里面的构造方法 __init__() 负责将类的实例化,而在 __init__() ...

  5. python的__new__方法

    https://www.cnblogs.com/kex1n/p/5991249.html https://blog.csdn.net/wwx890208/article/details/8053445 ...

  6. 【python】Python 之 __new__() 方法与实例化

    本文转自:http://www.cnblogs.com/ifantastic/p/3175735.html __new__() 是在新式类中新出现的方法,它作用在构造方法建造实例之前,可以这么理解,在 ...

  7. Python 的 __new__()方法与实例化

    __new__() 是新式类中才有的方法,它执行在构造方法创建实例之前.可以这么理解,在 Python 中类中的构造方法 __init__() 负责将类实例化,而在 __init__() 启动之前,_ ...

  8. [Python]python面向对象 __new__方法及单例设计

    __new__ 方法 使用 类名() 创建对象时,Python 的解释器 首先 会 调用 __new__ 方法为对象 分配空间 __new__ 是一个 由 object 基类提供的 内置的静态方法,主 ...

  9. Python中__new__方法为什么有人说是构造方法?有什么作用?

    __new__方法是Python新式类引入的,通常用于控制生成一个新实例的过程.它是类级别的静态方法,是在创建实例对象前执行,如果自定义类中没有重写该方法,则Python自动调用父类的方法,当所有父类 ...

随机推荐

  1. Inception系列之Inception_v1

    目前,神经网络模型为了得到更好的效果,越来越深和越来越宽的模型被提出.然而这样会带来以下几个问题: 1)参数量,计算量越来越大,在有限内存和算力的设备上,其应用也就越难以落地. 2)对于一些数据集较少 ...

  2. leetcode146 longest-substring-without-repeating-character

    题目描述 给定一个字符串,找出最长的不具有重复字符的子串的长度.例如,"abcabcbb"不具有重复字符的最长子串是"abc",长度为3.对于"bbb ...

  3. GraphX 在图数据库 Nebula Graph 的图计算实践

    不同来源的异构数据间存在着千丝万缕的关联,这种数据之间隐藏的关联关系和网络结构特性对于数据分析至关重要,图计算就是以图作为数据模型来表达问题并予以解决的过程. 一.背景 随着网络信息技术的飞速发展,数 ...

  4. 02 . Vue入门基础之条件渲染,列表渲染,事件处理器,表单控件绑定

    vue基础 声明式渲染 Vue.js 的核心是一个允许采用简洁的模板语法来声明式地将数据渲染进 DOM 的系统 Example1 <!DOCTYPE html> <html> ...

  5. java类学习

    public class test4 { public static void main(String args[]) { /** * 方法定义规则 * 修饰 类型 方法名(参数){ * 要完成的动作 ...

  6. UnixIPC之共享内存

    Unix-IPC之共享内存 一,共享内存的概念 共享内存通信技术是一种最快的可用IPC形式,它是针对其他通信机制运行效率低和设计的新型通信技术(其他的如:信号量,管道,套接字等).这种通信技术往往与其 ...

  7. tcp 输入 简析 转载

    正常来说 TCP 收消息过程会涉及三个队列: Backlog Queue sk->sk_backlog Prequeue tp->ucopy.prequeue Receive Queue  ...

  8. JavaScrip_12.23

    笔记系列,零散的知识点,准备以后复习整理使用 JavaScrip - 事件DOM绑定[将函数添加到一个元素对象的属性中] 1.事件 鼠标.键盘.操作等:所有的GUI都有 onclick(单击事件) 例 ...

  9. MySQL索引背后的数据结构及原理

    摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BT ...

  10. PHP反序列化漏洞-CVE-2016-7124(绕过__wakeup)复现

    前言 最近电脑也不知怎么了时不时断网而且我竟然找不出原因!!!很诡异....  其他设备电脑都OK唯独我的电脑 时好时坏 我仿佛摸清了我电脑断网的时间段所以作息时间都改变了  今天12点多断网刷了会手 ...