【一】什么是魔法方法
-
在类内部达到指定条件会自动触发的方法
【二】魔法方法
# 【1】__init__ : 实例化类得到对象的时候会自动触发 class Student(object): def __init__(self): print(f"实例化类的时候触发") # 实例化类的时候触发 s = Student() # 【2】__del__ : 当对象/对象关闭销毁的时候自动触发 # 场景:打开文件 open --> close class Student(object): def __init__(self): print(f"实例化类的时候触发") # 实例化类的时候触发 def __del__(self): print(f"当前在销毁的时候触发") # 当前在销毁的时候触发 s = Student() # 【3】__str__ : 在打印当前对象的时候可以定制打印当前对象的显示内容 # 必须且只能返回字符串类型的数据 def __str__(self): print(f"打印当前对象的时候触发") return self.name # 【4】__repr__ : 交互解释器会触发 def __repr__(self): print(f"与解释器交互的时候会触发") print('-------') return self.name # 【5】__doc__ : 打印类里面的注释内容的时候会触发 # 对象.__doc__ # 类.__doc__ __doc__ = "这是一个学生类" # 【6】__enter__ : 打开文档的时候会触发 with 语句触发 def __enter__(self): print(f"打开文档的时候会触发") print('-------') return self # 【7】__exit__ : 关闭文档的时候会触发 with 语句触发 def __exit__(self, exc_type, exc_val, exc_tb): print(f"关闭文档的时候会触发") print('-------') ... # 【8】__getattr__ : 获取当前对象的不存在的属性的时候触发 # __getattribute__ : 值不存在的时候会触发异常 def __getattr__(self, item): print(f'当前对象属性不存在的时候会触发') print(item) # 就是不存在的属性的变量名 # 父类里面有一个 __getattribute__ 能主动抛出值不存在的异常 super().__getattribute__(item) # 【9】__setattr__ : 设置对象的属性值的时候会触发(包括 __init__ 初始化属性) def __setattr__(self, key, value): print(f'设置当前对象属性的时候会触发 对象.key=value') print(f"key :>>>>> {key}") print(f"value :>>>>> {value}") # 【10】__setattr__ : 删除对象的属性值的时候会触发 def __delattr__(self, item): print(f'当前在删除属性的时候会触发') print(item) print('-------') # 【11】__setitem__ : 对象[key]=value 设置值的时候会触发 def __setitem__(self, key, value): print(f'设置属性的时候会触发 设置方式为 对象[key]=value') print(key, value) print('-------') # 用自己的名称空间字典放 self.__dict__[key] = value # 【12】__getitem__ : 获取属性的时候会触发 设置方式为 对象[key] def __getitem__(self, item): print(f'获取属性的时候会触发 设置方式为 对象[key]') print('-------') return self.__dict__[item] # 【13】__delitem__ : 删除属性的时候会触发 删除方式为 del 对象[key] def __delitem__(self, key): print(f'删除属性的时候会触发 删除方式为 del 对象[key]') print(key) print('-------') # 【14】__getattribute__: 负责正常对象。属性不存在的时候的报错方法 def __getattribute__(self,item): # s = Student(name='dream') # print(s) # <__main__.Student object at 0x0000023FE2084E50> # print(repr(s)) # 触发 __repr__ # print(s.__doc__) # print(Student.__doc__) # with Student('hope') as fp: # print(fp,type(fp)) # s = Student(name='dream') # print(s.name) # print(s.age) # s.age = 18 # del s.age # print(s.age) # s['gender'] = 'male' # print(s['gender']) # # del s['gender']
# 【15】 __call__ :触发条件是当前类()或对象()调用的时候 class Student: def __init__(self): print(f'__init__被触发') def __call__(self, *args, **kwargs): print(f"__call__被触发") # __call__ 可以放在两个位置 # 一个位置在当前对象的父类中 直接对象()会触发当前类的__call__ # 另一个位置在当前对象的父类的元类在会触发 s = Student() s() # callable:校验当前对象是否可被调用() # 类本身可以可以被任意调用的 print(callable(Student)) # True # 但是对象不可以直接被调用 # 想让对象也能()调用,就必须重写__call__ print(callable(s)) # True 如果将上面的__call__删掉 则s()就无法调用变为False