在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}属性不允许删除")运行结果: