Python 中,以双下划线__
包起来的方法,统称为:魔术方法(Magic Method)
魔术方法是一个类或对象中的特殊方法,和普通方法的区别在于,普通方法需要手动调用,而魔术方法是在特定时刻自动触发执行的
如果希望根据自己的程序定制自己特殊功能的类,那么就需要对这些魔术方法进行重写
1. __new__
(1). 说明:实例化对象方法
(2). 触发时机:在实例化时触发
(3). 参数:至少得有一个
cls
接收当前类,写法为__new__(cls, *args, **kwargs)
(4). 返回值:必须使用
return
关键字返回一个对象实例(5). 作用:实例化(创建)对象,开辟内存地址空间对象并返回
(6). 注意:实例化对象是
Object
类底层实现,其他类继承了Object
的__new__
才能够实现实例化对象
2. __init__
(1). 说明:初始化方法,相当于
java中的构造方法
,在__new__
执行后被调用(2). 触发时机:初始化对象时触发(区别于
__new__
实例化时的触发)(3). 参数:至少得有一个
self
接收__new__
方法返回的对象,写法为__init__(self, name, age)
(4). 返回值:无
(5). 作用:初始化对象的成员
(6). 注意:使用该方式初始化的成员都是直接写入对象当中,类中无法具有
3. __del__
(1). 说明:析构魔术方法
(2). 触发时机:当一块地址空间没有任何指针引用的时候被触发
在 Python 解释器中,当所有代码程序执行完成则会进行垃圾回收,也叫内存释放,这时就会触发
__del__
方法使用
del 对象名
显示删除引用关系时,如果此操作将某块地址空间的最后一个引用关系给删除,则会触发__del__
方法(3). 参数:仅只一个
self
参数接收对象(4). 返回值:无
(5). 作用:使用完对象时回收资源,没有指针引用的时候会调用,绝大多数时候不需要重写
(6). 注意:
del 对象名
不一定会触发当前方法,只有某块地址空间无任何引用时才会触发
4. __call__
(1). 说明:调用对象函数的魔术方法
(2). 触发时机:将对象当作函数调用时触发,使用形式为
对象名称()
,会默认调用__call__
函数里的内容(3). 参数:至少得有一个
self
接收对象,剩余参数根据调用时传入的参数决定,写法为__call__(self, args)
(4). 返回值:根据具体重写逻辑而定
(5). 作用:将复杂的步骤统一放在该函数内实现,减少调用的步骤,比较方便
(6). 注意:无
5. __str__
(1). 说明:当
print(对象名)
时想看到更多的信息时,可以重写__str__
方法,将想要输出的信息放在__str__
函数中返回(2). 触发时机:使用
print(对象名)
或者str(对象名)
的时候触发(3). 参数:一个
self
参数接收对象(4). 返回值:必须是字符串类型
(5). 作用:
print(对象名)
时可以自定义输出更多有用信息(6). 注意:无
class People: # 类名Person后面加不加(Object)效果是一样的,都表示继承自Object类
# 创建对象
def __new__(cls, *args, **kwargs):
print("调用__new__构造方法")
position = super().__new__(cls) # 调用父类的__new__()方法创建对象,开辟内存空间
# print(position) # <__main__.People object at 0x7fa19b8a6c10>
return position # 将创建的地址空间对象返回,交给__init__方法接收
# 实例化对象
def __init__(self, name, age):
self.name = name # 在__new__方法返回的内存空间地址中放置name属性
self.age = age # 在__new__方法返回的内存空间地址中放置age属性
# print(self) # <__main__.People object at 0x7fa19b8a6c10>
print("调用__init__初始化方法")
# 对象作为函数调用时的逻辑
def __call__(self, args):
print("调用__call__方法,接收到的参数为:%s" % args)
# 删除对象: 在(del 对象名后所对应的地址空间无任何引用时)或者程序执行结束之后
def __del__(self):
print("调用__del__析构方法,删除对象,释放内存空间")
# 自定义print(对象名)时的输出内容
def __str__(self):
return '对象的name是:' + self.name + ',对象的age是:' + str(self.age)
if __name__ == '__main__':
p = People('liuming', 20)
# print(p) # <__main__.People object at 0x7fa19b8a6c10>
p('abc') # 调用__call__方法
p1 = p
p2 = p
p3 = p # 截止到这里p对象所在的地址空间,共有4个对象都在引用,分别是对象:p,p1,p2,p3
del p3 # 删除的是p3对内存地址空间的引用关系,此时p对象所在的地址空间,共有3个对象在引用,分别是对象:p,p1,p2
del p2
del p1
del p # 自动调用__del__方法,因为p对象所在的地址空间已经没有任何对象在引用了,所以需要对内存地址进行回收释放
p4 = People('xiaohong', 18)
print(p4) # 对象的name是:xiaohong,对象的age是:18---注意:此时输出的不再是地址空间值了,而是__str__函数自定义return的内容
print(str(p4)) # 输出内容同print(p4)
1.调用__new__构造方法
2.调用__init__初始化方法
3.调用__call__方法,接收到的参数为:abc
4.调用__del__析构方法,删除对象,释放内存空间
5.调用__new__构造方法
6.调用__init__初始化方法
7.对象的name是:xiaohong,对象的age是:18
8.对象的name是:xiaohong,对象的age是:18
9.调用__del__析构方法,删除对象,释放内存空间
p = People('liuming', 20)
与p4 = People('xiaohong', 18)
该代码块执行时都会自动调用__new__
与__init__
函数,对应结果输出为:第1,2,5,6行
p('abc')
该代码块执行时会自动调用__call__
函数,对应结果输出为:第3行
del p
该代码块执行时会自动调用__del__
函数,对应结果输出为:第4行
注意:当执行代码块del p3/p2/p1
时都没有自动调用__del__
函数
是因为此时p对象
所指向的地址空间还有p这个对象
在引用,指针引用关系还存在
直到del p
执行时才将该地址空间唯一的指针引用关系给销毁了,所以就调用了__del__
函数。
print(p4)
与print(str(p4))
该代码块执行时会自动调用__str__
函数,对应结果输出为:第7,8行
所有代码块全部执行完毕后,Python解释器的垃圾回收机制会将分配的内存进行释放回收,此时也会调用__del__
函数,对应结果输出为:第9行
欢迎关注 无量测试之道
公众号,回复领取资源
Python+Unittest框架API自动化、
Python+Unittest框架API自动化、
Python+Pytest框架API自动化、
Python+Pandas+Pyecharts大数据分析、
Python+Selenium框架Web的UI自动化、
Python+Appium框架APP的UI自动化、
Python编程学习资源干货、
Vue前端组件化框架开发、
资源和代码 免费送啦~
文章下方有公众号二维码,可直接微信扫一扫关注即可。
备注:我的个人公众号已正式开通,致力于IT互联网技术的分享。
包含:数据分析、大数据、机器学习、测试开发、API接口自动化、测试运维、UI自动化、性能测试、代码检测、编程技术等。
微信搜索公众号:无量测试之道
添加关注,让我们一起共同成长!