上节《第8.5节 Python类中的__new__方法和构造方法__init__关系深入剖析:执行顺序及参数关系案例详解》通过案例详细分析了两个方法的执行顺序,不知大家是否注意到了,在上述代码中__new__方法调用父类的__new__方法时,传递参数只传递了cls一个实参,而没有传递后面两类参数(在本例中只有第一类参数中有1个实参10)。这个问题也困扰了老猿,我们先验证一下,如果传递全部参数会怎样。
一、 案例1:调用object类的__new__传参验证
- 我们将上节的类中的__new__方法改成传递全部参数后,类定义如下:
class Cir():
def __new__(cls,*args,**kwargs):
print("Python传递给__new__的参数:\n***cls: ",cls,"\n***args: ",args,"\n***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
- 定义实例变量:
cir=Cir(10)
执行结果报错:TypeError: object.__new__() takes no arguments
- 完整执行截屏如下:
5. 案例分析:
本案例定义的类没有自定义父类,因此其父类就是object,调用super().__new__方法执行的就是object类的__new__方法。结合上节正常执行执行的情况说明,不能传递所有参数,只能传递类名给object. __new__方法才能通过Python检查。
- 我们来看看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__只能传入一个参数。
- 我们再到Python3.73文档中查一下:
中文版:
英文版:
从上面也说明是可以传多个值的。所以老猿没有明白这个地方实际使用时为什么不能传递多个值,如果哪位大拿研究清楚了欢迎给老猿指导。
二、 案例2:调用自定义父类的__new__传参验证
- 案例说明
定义两个类,Vehicle类和Car类,Car是从Vehicle派生的,Car重写了__new__方法,验证几种情况:
- Vehicle类没有重写__ new__方法;
- Vehicle类重写__ new__方法,只传入cls;
- Vehicle类重写__ new__方法,传入所有参数。
- 案例代码:
- Vehicle类没有重写__ new__方法,Car重写该方法并调用父类传递所有参数,执行截屏如下:
说明还是不行,老猿认为这是因为Vehicle没有重写__ new__方法,就会调用其直接父类object的__ new__方法,导致不行。 - Vehicle类和Car类都重写__ new__方法,Car类调用父类的该方法时传递所有参数,而Vehicle类调用父类的该方法时只传cls参数,执行截屏如下:
可以看到执行成功。 - 还有一种情况,就是Vehicle类调用父类的该方法时传递所有参数,结果还是报错,在此就不提供截图了
三、 结论
通过以上案例验证,可以确认:
- 调用object. __ new__方法时,只能传cls参数,否则会报错;
- 调用自定义类的自定义父类__ new__方法,可以传所有参数,要看父类的__ new__方法定义的参数是怎么定义的。
老猿Python(https://blog.csdn.net/LaoYuanPython)系列文章用于逐步介绍老猿学习Python后总结的学习经验,这些经验有助于没有接触过Python的程序员可以很容易地进入Python的世界。
欢迎大家批评指正,谢谢大家关注!