第8.6节 Python类中的__new__方法深入剖析:调用父类__new__方法参数的困惑
上节《第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
- 完整执行截屏如下:
- 案例分析:
本案例定义的类没有自定义父类,因此其父类就是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的世界。
欢迎大家批评指正,谢谢大家关注!
第8.6节 Python类中的__new__方法深入剖析:调用父类__new__方法参数的困惑的更多相关文章
- 第8.4节 Python类中不是构造方法却胜似构造方法的__new方法__深入剖析:语法释义
一. 引言 在本博前面的内容都对构造方法__init__进行了介绍,也在前面章节引入了__new__方法,但老猿认为__new__方法比构造方法__init__更应该属于构造方法.这是因为在Py ...
- 第7.17节 Python类中的静态方法装饰器staticmethod 定义的静态方法深入剖析
第7.17节 Python类中的静态方法装饰器staticmethod 定义的静态方法深入剖析 静态方法也是通过类定义的一种方法,一般将不需要访问类属性但是类需要具有的一些能力可以静态方法提供. 一 ...
- 第7.14节 Python类中的实例方法详析
第7.14节 Python类中的实例方法详析 一. 实例方法的定义 在本章前面章节已经介绍了类的实例方法,实例方法的定义有三种方式: 1. 类体中定义实例方法 第一种方式很简单,就是在类体 ...
- 第8.12节 Python类中使用__dict__定义实例变量和方法
上节介绍了使用实例的__dict__查看实例的自定义属性,其实还可以直接使用__dict__定义实例变量和实例方法. 一. 使用__dict__定义实例变量 语法: 对象名. dict[属性名] = ...
- 第8.9节 Python类中内置的查看直接父类的__bases__属性
终于介绍完了__init__方法和__new__方法,接下来轻松一下,本节介绍类中内置的__bases__属性. 一. 语法释义 Python 为所有类都提供了一个 bases 属性,通过该属性可以查 ...
- 第8.5节 Python类中的__new__方法和构造方法__init__关系深入剖析:执行顺序及参数关系案例详解
上节介绍了__new__()方法这个比构造方法还重要的方法的语法,本节通过案例来详细剖析__new__()方法的细节以及它与构造方法之间的关系. 一. 案例说明 本节以圆Cir类为例来说明,为了 ...
- python基础之继承实现原理、子类调用父类的方法、封装
继承实现原理 python中的类可以同时继承多个父类,继承的顺序有两种:深度优先和广度优先. 一般来讲,经典类在多继承的情况下会按照深度优先的方式查找,新式类会按照广度优先的方式查找 示例解析: 没有 ...
- 第8.11节 Python类中记录实例变量属性的特殊变量__dict__
一. 语法释义 调用方法:实例. __dict__属性 __dict__属性返回的是实例对象中当前已经定义的所有自定义实例变量的名和值,用字典存储,每个元素为一个"实例变量名:值" ...
- 第8.14节 Python类中内置方法__str__详解
一. object类内置方法__str__和函数str 类的内置方法__str__和内置函数str实际上实现的是同一功能,实际上str调用的就是__str__方法,只是调用方式不同,二者的调用语法如下 ...
随机推荐
- 【Kata Daily 190918】Spacify(插空)
题目: Modify the spacify function so that it returns the given string with spaces insertedbetween each ...
- 3.4 spring5源码系列--循环依赖的设计思想
前面已经写了关于三篇循环依赖的文章, 这是一个总结篇 第一篇: 3.1 spring5源码系列--循环依赖 之 手写代码模拟spring循环依赖 第二篇: 3.2spring源码系列----循环依赖源 ...
- 如何使用 gitlab 或 github 执行npm run build
一: 如何快速搭建一个组件库 首先,我们介绍一个快速包装组件库的工具:https://github.com/yanhaijing/jslib-base 按照文档来,就简单几步: npx @js ...
- mysql查询上月天数/当月第一天/上月第一天
select (DATEDIFF(DATE_ADD(curdate(), INTERVAL - DAY(curdate())+ 1 DAY), date_add(curdate()- DAY(curd ...
- 运维告警排班太复杂?试试Cloud Alert智能告警排班
前言: 之前的几篇文章有说过,通过智能告警平台Cloud Alert,将指定条件的告警以多样化的通知方式,通知到指定的人,其中的通知的方式包含电话.短信.邮件.微信.APP.钉钉等. 本篇文章就来说下 ...
- tcp 保活定时器分析 & Fin_WAIT_2 定时器
tcp keepalive定时器 http server 和client端需要防止"僵死"链接过多!也就是建立了tcp链接,但是没有报文交互, 或者client 由于主机突然掉电! ...
- Innodb之全局共享内存
参考链接: https://blog.csdn.net/miyatang/article/details/54881547 https://blog.csdn.net/wyzxg/article/de ...
- Python面试题_中级版
Python 面试题 1.Python是如何进行内存管理的 对象引用机制.垃圾回收机制.内存池机制 1.1对象引用机制 Python内部使用引用计数,来保持追踪内存中的对象,所有对象都有引用计数. 引 ...
- C语言设计模式(命令模式)
#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0])) typedef int (*parse_func)(const char *data,size_t len ...
- Linux安装部署Redis(超级详细)
前言 网上搜索了一筐如何在Linux下安装部署Redis的文章,各种文章混搭在一起勉强安装成功了.自己也记录下,方便后续安装时候有个借鉴之处. Redis版本 5.0.4 服务器版本 Linux Ce ...