在Python中,所有以__双下划线包起来的方法,都统称为"魔术方法"
在之前的接触中,我们有见过__init__,当然也是很常见的,除了__init__,我们也要了解下__new__,__del__,
__getattribute__,__getattr__,__setattr__,__delattr__
class Stu:
def __init__(self, stu_no, stu_name, stu_sex):
"""
:param stu_no: --->str
:param stu_name: --->str
:param stu_sex: ---->str
"""
self.stu_no = stu_no
self.stu_name = stu_name
self.stu_sex = stu_sex
if __name__ == "__main__":
stu_01 = Stu("Stu_001", "小明", "女")
print(stu_01.weight)
1. 类的实例化时涉及的魔法函数:
1) __init__,__new__ : 】
在对象进行实例化时,通过__init__讲参数传给通过__new__而创建的类的实例,进而实现类的实例化,所以类的实例化时,
__init__不一定会被调用,但是__new__先是会被首先掉用的
2) __del__: 在对象的生命周期结束时, __del__
会被调用,类似于一个对象不用了之后进行回收了
2. 属性访问或者修改时所涉及的几个魔法函数:
1) __getattribute__:访问属性时,就会调用该函数一次,无论属性存不存在
通过截图可知:访问属性时,就会调用该函数一次,无论属性存不存在,但是返回的值却不对,那如何处理才会得到我们预期中想要的结果呢? 那么我们就需要对该函数进行重写,如下所示:
def __getattribute__(self, item):
# 当对象访问属性时,会自动触发这个方法,有这个方法来决定返回的属性值
try:
return super().__getattribute__(item) # 重写父类__getattribute__()方法
except AttributeError as msg: # 访问属性出现异常时,返回None
print(f"{item}属性不存在")
return None
这是代码运行,运行结果就是:
2)_getattr__(self, item): 跟__getattribute__(self, item)函数类似的功能的魔法函数,只不过该函数相当于是__getattribute__(self, item)的优化版,无需进行try...except处理
def __getattr__(self, item):
# 当访问属性时,属性不存在时,也不会报错,自动返回None,当访问属性存在时,返回属性值,
# 相当于__getattribute__的自带捕获异常处理
print("调用__getattr__(self, item)魔法函数")
代码运行结果:
3) __setattr__(self, key, value) :设置属性时,包括:init初始化传参,对象新增属性,都调用该魔术方式
通过截图看出,设置属性时,包括:init初始化传参,对象新增属性,都调用该魔术方式,但是最终再想要访问新建的属性时,却报错,此时我们需要怎么处理呢? 重写父类Object __setattr__(self, key, value)
def __setattr__(self, key, value): # 设置属性时会被触发
print("设置属性时会被触发_setattr__函数")
super().__setattr__(key, value)
运行结果如下:
4) __delattr__(self, item) : 删除属性时会被触发
def __delattr__(self, item): # 删除属性时会被触发
print(f"这个是__delattr__,正在删除{item}属性")
如果说,不允许某些属性被删除,那么可以进行如下处理:
def __delattr__(self, item): # 删除属性时会被触发
if item not in ["stu_no", "stu_name", "stu_sex"]: # 则name2属性不允许删除
print(f"这个是__delattr__,正在删除{item}属性")
super().__delattr__(item)
else:
print(f"{item}属性不允许删除")
运行结果: