• 第8.6节 Python类中的__new__方法深入剖析:调用父类__new__方法参数的困惑


    上节《第8.5节 Python类中的__new__方法和构造方法__init__关系深入剖析:执行顺序及参数关系案例详解》通过案例详细分析了两个方法的执行顺序,不知大家是否注意到了,在上述代码中__new__方法调用父类的__new__方法时,传递参数只传递了cls一个实参,而没有传递后面两类参数(在本例中只有第一类参数中有1个实参10)。这个问题也困扰了老猿,我们先验证一下,如果传递全部参数会怎样。
    一、 案例1:调用object类的__new__传参验证

    1. 我们将上节的类中的__new__方法改成传递全部参数后,类定义如下:
    class Cir():
       def __new__(cls,*args,**kwargs):
           print("Python传递给__new__的参数:
    ***cls: ",cls,"
    ***args: ",args,"
    ***kwargs:",kwargs)
           inst = super().__new__(cls,*args,**kwargs)  #将所有参数都传递进去
           print("__new__返回值:",inst)
           return inst
    
       def __init__(self,radius):
           print("In init,self的值为:",self,", radius的值为:",radius)
           self.radius = radius
    
    1. 定义实例变量:
    cir=Cir(10)
    执行结果报错:TypeError: object.__new__() takes no arguments
    
    1. 完整执行截屏如下: 在这里插入图片描述
    2. 案例分析:
      本案例定义的类没有自定义父类,因此其父类就是object,调用super().__new__方法执行的就是object类的__new__方法。结合上节正常执行执行的情况说明,不能传递所有参数,只能传递类名给object. __new__方法才能通过Python检查。
    1. 我们来看看Python的相关帮助文档
    执行help(object.__new__),输出内容:
    Help on built-in function __new__:
    
    __new__(*args, **kwargs) method of builtins.type instance
        Create and return a new object.  See help(type) for accurate signature.
    

    截图如下:
    在这里插入图片描述
    从上面没有看出object. __new__只能传入一个参数。

    1. 我们再到Python3.73文档中查一下:
      中文版:
      在这里插入图片描述

    英文版:
    在这里插入图片描述
    从上面也说明是可以传多个值的。所以老猿没有明白这个地方实际使用时为什么不能传递多个值,如果哪位大拿研究清楚了欢迎给老猿指导。

    二、 案例2:调用自定义父类的__new__传参验证

    1. 案例说明
      定义两个类,Vehicle类和Car类,Car是从Vehicle派生的,Car重写了__new__方法,验证几种情况:
    1. Vehicle类没有重写__ new__方法;
    2. Vehicle类重写__ new__方法,只传入cls;
    3. Vehicle类重写__ new__方法,传入所有参数。
    1. 案例代码:
    1. Vehicle类没有重写__ new__方法,Car重写该方法并调用父类传递所有参数,执行截屏如下:
      在这里插入图片描述
      说明还是不行,老猿认为这是因为Vehicle没有重写__ new__方法,就会调用其直接父类object的__ new__方法,导致不行。
    2. Vehicle类和Car类都重写__ new__方法,Car类调用父类的该方法时传递所有参数,而Vehicle类调用父类的该方法时只传cls参数,执行截屏如下:
      在这里插入图片描述
      可以看到执行成功。
    3. 还有一种情况,就是Vehicle类调用父类的该方法时传递所有参数,结果还是报错,在此就不提供截图了

    三、 结论
    通过以上案例验证,可以确认:

    1. 调用object. __ new__方法时,只能穿cls参数,否则会报错;
    2. 调用自定义类的自定义父类__ new__方法,可以传所有参数,要看父类的__ new__方法定义的参数是怎么定义的。

    老猿Python(https://blog.csdn.net/LaoYuanPython)系列文章用于逐步介绍老猿学习Python后总结的学习经验,这些经验有助于没有接触过Python的程序员可以很容易地进入Python的世界。
    欢迎大家批评指正,谢谢大家关注!

  • 相关阅读:
    29-赫夫曼树
    28-线索化二叉树
    27-顺序存储二叉树
    26-二叉树的遍历查找和删除
    25-二叉树的概念
    24-逻辑结构分析
    23-哈希表
    22-查找算法
    21-堆排序
    Mui-列表/table-view
  • 原文地址:https://www.cnblogs.com/LaoYuanPython/p/11087679.html
Copyright © 2020-2023  润新知