python中__init__()、__new__()、__call__()、__del__()几个魔法方法的用法
关于__new__()的用法参考:
http://www.myhack58.com/Article/68/2014/48183.htm
正文:
一、__new__()的用法:
__new__()是在新式类中新出现的方法,它作用在构造方法建造实例之前,可以这么理解,在Python 中 存在于类里面的构造方法__init__()负责将类的实例化,而在__init__()启动之前,__new__()决定是否 要使用该__init__()方法,因为__new__()可以调用其他类的构造方法或者直接返回别的对象来作为本类 的实例。
# encoding:utf-8class A(object):def __new__(cls, x):print 'this is in A.__new__, and x is ', xreturn super(A, cls).__new__(cls)def __init__(self, y):print 'this is in A.__init__, and y is ', yclass C(object):def __new__(cls, n):print 'this is in C.__new__, and n is ', nreturn super(C, cls).__new__(cls)def __init__(self, a):print 'this is in C.__init__, and a is ', aclass B(A):def __new__(cls, z):print 'this is in B.__new__, and z is ', zreturn A.__new__(cls, z)def __init__(self, m):print 'this is in B.__init__, and m is ', m# class B(A): # def __new__(cls, z): # print 'this is in B.__new__, and z is ', z # return object.__new__(cls) # def __init__(self, m): # print 'this is ni B.__init__, and m is ', mif __name__ == '__main__':a = A(100)print '=' * 20b = B(200)print type(b)
执行的结果为:
this is in A.__new__, and x is 100 this is in A.__init__, and y is 100 ==================== this is in B.__new__, and z is 200 this is in A.__new__, and x is 200 this is in B.__init__, and m is 200 <class '__main__.B'>
说明:
1.定义A类作为下面类的父类,A类继承object类,因为需要重写A类的__new__()函数,所以需要继承object基类,成为新式类,经典类没有__new__()函数;
2.子类在重写__new__()函数时,写return时必须返回有继承关系的类的__new__()函数调用,即上面代码中的B类继承自A类,则重写B类的__new__()函数,写return时,只能返回A.__new__(cls)或者object.__new__(cls),不能返回C类的;
3.由注释掉的代码执行结果可以看出,B类虽然继承自A类,但是如果没有重写B类的__new__()函数,则默认继承的仍是object基类的__new__(),而不是A的;
4.B类的__new__()函数会在B类实例化时被调用,自动执行其中的代码语句,但是重写__new__()函数不会影响类的实例化结果,也就是说不管写return时返回的是A的还是object的,B类的实例化对象就是B类的,而不会成为A类的实例化对象;只是在实例化时,如果返回的是A.__new__(cls),则会执行A类中定义的__new__()函数;
5.__new__()函数确定了类的参数的个数,object类默认定义的__new__()函数的参数为(cls, *more),但如果在子类中重写了__new__(cls, x), 则实例化类时,需要传入一个x参数,而__init__()函数接受到的有两个参数,一个是实例化生成的实例对象self代替,一个是传入的实参x的值;
>>> >>> class A(object):def __init__(self, x):self.x = xprint '__init__ called.'def foo(self):print self.x>>> >>> a = A('123') __init__ called. >>> >>> a.foo() 123 >>>
在A('123')实例化类时,自动调用__init__()方法定义的self.x = x和print '__init__ called.',我们能看到‘__init__ called.’被打印,看不到self.x = x的执行,但是在调用a.foo()时,能执行成功,就是拜self.x = x的功能所赐;因为如果没有__init__()方法中的self.x = x,实例对象将无法追溯到foo()函数中的self.x是从哪里来的,从而会报错;也就是在__init__()函数中将外部传入的参数x赋值给self.x,从而是self.x在类A中畅行无阻;
三.__call__()的用法
__call__()方法能够让类的实例对象,像函数一样被调用;
>>> >>> class A(object):def __call__(self, x):print '__call__ called, print x: ', x>>> >>> a = A() >>> a('123') __call__ called, print x: 123 >>>
看a('123')这是函数的调用方法,这里a实际上是类对象A的实例对象,实例对象能想函数一样传参并被调用,就是__call__()方法的功能;
四、__del__()的用法
如果__new__()和__init__()函数时类的构造函数(即在类实例化时自动执行函数中定义的内容),那么__del__()是类的析构函数,是python垃圾回收机制的实际应用,当类的所有引用都被删除后,该类就会被系统从内存中删除,注意是所有的引用都被删除哦,而不是每一次删除;
>>> class D(object):def __init__(self):print 'this is D.__init__()'def __del__(self):print 'this is D.__del__()'>>> >>> d = D() this is D.__init__() >>> >>> d2 = d >>> d3 = d >>> >>> del d >>> del d2 >>> del d3 this is D.__del__() >>>
将D()实例化对象赋值给d,后d2,d3都是指向D()的这次实例化对象,删除d和d2的引用都不会触发__del__()函数,最后一个d3的引用被删除,就会触发__del__(),此时D()的这一次实例化的对象就被清除;
最后:
用一段简单的代码,来总体感受一下三个方法的用法和区别:
>>> >>> class A(object):def __init__(self, x):print 'x in __init__', xdef __new__(cls, y):print 'y in __new__', yreturn super(A, cls).__new__(cls)def __call__(self, z):print 'z in __call__', zdef __del__(self):print 'this is in A.__del__()'>>> >>> A('123')('abc') y in __new__ 123 x in __init__ 123 z in __call__ abc this is in A.__del__() >>>
由执行结果可以看出,虽然__init__()方法定义在__new__()方法之前,但是结果中先展示了__new__()方法的执行结果;
转载于:https://www.cnblogs.com/zanjiahaoge666/p/7490824.html
python中__init__()、__new__()、__call__()、__del__()几个魔法方法的用法相关推荐
- Python中被双下划线包围的魔法方法
基本的魔法方法 __new__(cls[, ...]) 用来创建对象 1. __new__ 是在一个对象实例化的时候所调用的第一个方法2. 它的第一个参数是这个类,其他的参数是用来直接传递给 __in ...
- Python中面向对象self获取对象属性,魔法方法
类和对象 类(Class) 由3个部分构成 01). 类的名称:类名 02). 类的属性:一组数据 03). 类的方法:允许对进行操作的方法 (行为) 定义类 object 是Python 里所有类的 ...
- python 中__init__ 与 __call__ 的区别
可以看到, 在类实例化的时候,会调用__init__ 实例化了之后,再调用实例化的对象的时候,这个时候调用的是__call__ class test:def __init__(self, a, b): ...
- python中__init__下划线怎么打出来_除了__init__ 这个双下划线函数,你在定义 Python 类时还使用过哪些双下划线函数?...
Python 中以双下划线开头跟结尾方法称为 magic method 即 魔法方法,我之前总结过一些常用的给你参考:__new__ && __init__ 他们之间的关系是面试中经常 ...
- Python中__init__方法有什么作用
Python中__init__方法有什么作用 当使用类名()的方法去创建对象的时候 python解释器会自动调用__init__方法 因此可以在__init__方法中做一些初始化的设定 在每次创建新对 ...
- python中__init__()作用
Python中__init__函数的作用 python中__init__()函数即表示构造函数,通常在Python中创建类中见到. 代码如下: cl ...
- python中用于释放类占用的资源的方法是()_mooc大学英语词汇期末答案
把两个已有项目放到一起,就是一个新项目,这种项目来源属于(?? ) 答:整合 辩证法同形而上学的斗争 答:是从属于唯物主义同唯心主义的斗争,并同这种斗争交织在一起的 中国大学MOOC: 广义的计划是对 ...
- python中用于释放类占用的资源的方法是()_2020超星尔雅龙华医院-五项答案新版...
智慧职教: 某企业生产甲乙两种产品,销售额分别为100万元和400万元,边际贡献分别为50万元和200万元.则企业综合边际贡献率为( ). 答:0.5 以下成本中属于变动成本的有如(? )等. 答:进 ...
- 第7.26节 Python中的@property装饰器定义属性访问方法getter、setter、deleter 详解
第7.26节 Python中的@property装饰器定义属性访问方法getter.setter.deleter 详解 一. 引言 Python中的装饰器在前面接触过,老猿还没有深入展开介绍装饰 ...
- python中常见的三种选择结构_在Python中,实现多分支选择结构的最佳方法是
在Python中,实现多分支选择结构的最佳方法是 答:if-elif-else 绘制建筑平面图时,被剖切的墙用 线绘制,定位轴线用 线绘制 答:粗实 细点画 智慧职教: 下列关于书写住院病历的叙述不正 ...
最新文章
- 在Ubuntu上安装openResty #1
- java怎么获取传入路径_java如何获取jsp页面上传的文件路径
- 第六篇:python基础之文件处理
- spring 事务隔离级别和传播行为_Java工程师面试1000题146-Spring数据库事务传播属性和隔离级别...
- 飞鸽传书该如何去优化?
- surface mesh framework运行
- Druid的Segment Balance及其代价计算函数分析
- 15.10. Session/Cookie
- redis新数据类型-bitmaps
- java fri星期转_Java日期时间以及日期相互转换
- 华林SAP论坛(华林自建的SAP论坛)
- jumpserver 添加Windows主机
- 网易云音乐api歌单数据获取
- S2SH药膳馆会员管理系统计算机专业毕业论文java毕业设计开题报告
- sin cos 查表法算法解析
- About Sealed
- python中什么是一个无序的不重复元素序列_无序Python集的“顺序”
- Spring的前世今生: Spring5.0已经出来了,Springboot已经风靡全球, Spring怎么一步一步走过来的, 让我们看看其前世今生~~~
- 计算机毕业的人有很多不从事IT行业
- 名词解释第八讲:公钥
热门文章
- 内的图标_从零开始画图标系列:线性图标设计实战演示!
- apicloud开发时的一些注意点
- PHP7.0,PHP7.1.x新特性
- Location 对象操作 URL 使用详解
- 29. Divide Two Integers[M]两数相除
- HTTP和HTTPS笔记
- [SHOI2008]堵塞的交通
- 关于一个flask的服务接口实战(flask-migrate,flask-script,SQLAlchemy)
- [HAOI2007] 修筑绿化带
- mui多层tab切换上拉加载的实现