__init__(self,*args,**kwargs)
在创建完对象之后 会自动调用, 它完成对象的初始化的功能
*args 接收无指定参数
**kwargs 接收指定参数,以字典形式返回
__str__()
返回一个对象的描述信息,只有输出该类的对象才会被调用
classCat:
#初始化对象
def__init__(self,new_name,new_age):
self.name=new_name
self.age=new_age
def__str__(self):
return"%s的年龄是:%d"%(self.name,self.age)
tom=Cat("汤姆",40)
print(tom)
'''
>>>汤姆的年龄是:40
'''
__del__()
析构函数,同__init__方法相反,__del__在对象销毁时被调用,往往用于清除数据或还原环境等操作。比如在类中的其他普通方法中实现了插入数据库的语句,当对象被销毁时我们需要将数据还原,那么这时可以在__del__方法中实现还原数据库数据的功能。
__new__(cls,*args,**kwargs)
往往认为__init__是实例化时调用的第一个方法(注意前面讲解__init__方法时讲的是实例化后调用的第一个方法,一字之差),但其实实例化时调用的第一个方法是__new__方法。第一个必须传入的参数是cls,代表需要实例化的类
1、当__new__()和__init__()同时存在时,先调用__new__()2、奇怪的是并没有调用__init__方法,这是为什么呢?实际上,__new__是负责对当前类进行实例化,如果将实例对象进行返回并传给__init__方法,__init__方法中的self就是指代__new__传过来的对象,所以再次强调,__init__是实例化后调用的第一个方法。
classDemo:
def__new__(cls,*args,**kwargs):
print('调用__new__方法\n')
returnobject.__new__(cls)# 注意改行代码
def__init__(self):
print('调用__init__方法')
d=Demo()
'''
>>>调用__new__方法
调用__init__方法
'''
只有__new__方法正确return了当前类cls的实例,__init__方法才会被调用。特别需要说明的是,__new__方法中一定是返回父类的__new__方法来创建对象,如果返回当前对象会造成死循环。
3、__new__方法有什么作用呢?
3.1、继承不可变类 当继承一些不可变的class时(比如int, str, tuple),__new__方法提供了自定义这些类的实例化过程的途径。比如我们自定义类NewInt要继承int类,并且让传入的任何数最后都被转换成正整数
classNewInt(int):
def__new__(cls,value):
print('调用__new__方法\n')
returnint.__new__(cls,abs(value))
a=NewInt(-4.822)
print(a)
'''
>>>调用__new__方法
4
'''
自定义类NewInt继承于类int,但由于类int为不可变的,那么可以通过重写__new__方法,在对父类int实例化时作出需要的更改。
3.2、实现单例模式 一个经典设计模式,一个类只能被实例化一次,实例对象在第一次实例化时就已经固定,从第二次以后其实一直都是用的第一次实例化的对象,相当于全局。我们先来看非单例模式的情况。
classDemo:
def__init__(self,name):
print('我是 %s'%(name))
d1=Demo('小明')
d2=Demo('小红')
print(d1)
print(d2)
'''
我是 小明我是 小红<__main__.Demo object at 0x00000000021FC550><__main__.Demo object at 0x00000000021FC710>
'''
使用__init__方法,没有做其他特殊的处理,然后通过Demo类实例化了两个对象分别是d1和d2,最后输出两个对象,即他们的内存地址。可以看到d1和d2占用的是不同的内存地址,说明这里的Demo类被实例化了2次。
classDemo:
__isinstance=False# 创建私有变量判断是否被实例化
def__new__(cls,*args,**kwargs):
ifnotcls.__isinstance:# 如果被实例化了
cls.__isinstance=object.__new__(cls)# 否则实例化
returncls.__isinstance# 返回实例化的对象
def__init__(self,name):
print('我是 %s'%(name))
d1=Demo('小明')
d2=Demo('小红')
print(d1)
print(d2)
'''
>>> 我是 小明
>>> 我是 小红
>>> <__main__.Demo object at 0x00000000023FC710>
>>> <__main__.Demo object at 0x00000000023FC710>
'''
无论表面上使用Demo实例化多少次,其实都是同一个对象,内存地址也是一样的。