Python中的魔术方法大全
目录:
1.__init__初始化方法
5.__len__方法
6.__str__方法
10.__getattribute__
11.__getattr__
魔术方法
一种特殊的方法而已
特点
魔术方法种类
1.__init__初始化方法*******
触发时机:实例化对象之后触发
作用:为对象添加对象的所属成员
参数:self,接收当前对象,其他的参数根据实例化的传参决定
返回值:无
注意事项:无
# _author:"Ma ren" # date: 2023/2/23 # __init__:初始化魔术方法 class Human: # 属性 name = '张三' age = 18 gender = 'male' skin = 'yellow' # 方法 def __init__(self,name,gender,age): # name是__init__的形参 print('__init__方法被执行') # print(self) # 为对象添加成员 self.name = name # self.name中的name是对象的成员 self.gender = gender self.age = age def eat(self): print('吃饭方法') def run(self): print('跑步方法') def sleep(self): print('睡觉方法') # 实例化一个人的对象 h1 = Human('lxx','male',18) #<1.制作一个对象,2.为对象初始化操作> print(h1.__dict__) # 打印对象成员
触发时机:实例化对象的时候触发
作用:管理控制对象的生成过程
参数:一个cls接收当前类,其他的参数根据实例化的参数决定
返回值: 可有可无 没有返回值 实例化结果为None
注意事项:__new__魔术方法跟__init__的魔术方法参数一致(除了第一个)
# _author:"Ma ren" # date: 2023/2/23 # __new__构造方法 class Human: # 属性 name = '张三' age = 18 gender = 'male' skin = 'yellow' # 方法 # 魔术方法 def __new__(cls, *args, **kwargs): # print('__new__方法被触发') # return 2 # 自己控制对象的生成(女的生,男的不生) # print(args) if '男' in args: # 不生成对象 pass else: # 生成对象且返回 return object.__new__(cls) # object上帝之手 def eat(self): print('吃饭方法') def run(self): print('跑步方法') def sleep(self): print('睡觉方法') h1 = Human('女') # 实例化对象【1.制作一个对象(new),2.初始化对象】 print(h1) # 利用__new__方法来一个狸猫换太子 # _author:"Ma ren" # date: 2023/2/23 class Monkey: pass class Human: def __new__(cls, *args, **kwargs): return object.__new__(Monkey) pass # 看似使用人类造对象,实际却生成了一个猴子对象 human_obj = Human() print(human_obj)
触发时机:对象被系统回收的时候触发
作用:回收系统使用过程中的信息和变量
参数:一个self接收当前对象
返回值:无
注意事项:无
# _author:"Ma ren" # date: 2023/2/23 # __del__魔术方法 class Human: # 属性 name = '张三' age = 18 gender = 'male' skin = 'yellow' # 方法 def eat(self): print('吃饭方法') def run(self): print('跑步方法') def sleep(self): print('睡觉方法') # 析构方法 def __del__(self): print('__del__方法被触发') h = Human() print(h) # 主动删除对象 del h # 删除对象,系统回收对象 print('=================')
触发时机:将对象当做函数调用的时候自动触发
作用:常用语归结/对象的操作步骤,方便后期调用
参数:一个self接收当前对象,其余的参数根据需求添加
返回值:可以有,也可以没有
注意事项:无
# _author:"Ma ren" # date: 2023/2/25 # # 声明一个类 # class Human: # # 成员属性 # name = '张三' # gender = 'famale' # age = 18 # # # 成员方法 # # 魔术方法 # def __call__(self, *args, **kwargs): # print('__call__方法被触发') # # def eat(self): # print('吃的方法') # # def cry(self): # print('55555555555~~~~') # # # # 实例化一个对象 # zs = Human() # print(zs) # # # 对象能够加()调用吗?一般情况下是不行的 # zs() # __call__方法的作用 # 以制作蛋糕为例子 class MakeCake: # 和面 def huomian(self): print('和面') # 发酵 def fajiao(self): print('发酵') # 烘烤 def hongkao(self): print('烘烤') # 切型 def qiexing(self): print('切型') # 抹奶油 def monaiyou(self): print('抹奶油') # 加水果 def jiashuiguo(self): print('加水果') # 打包 def dabao(self): print('打包') # 封装成一个函数 # def getCake(self): # self.huomian() # self.fajiao() # self.hongkao() # self.qiexing() # self.monaiyou() # self.jiashuiguo() # self.dabao() # 更进一步,封装成__call__方法 def __call__(self): self.huomian() self.fajiao() self.hongkao() self.qiexing() self.monaiyou() self.jiashuiguo() self.dabao() mc1 = MakeCake() # 如果每次都这样调用制作蛋糕的方法,比较繁琐,考虑将这些步骤封装到一个方法中 # mc1.huomian() # mc1.fajiao() # mc1.hongkao() # mc1.qiexing() # mc1.monaiyou() # mc1.jiashuiguo() # mc1.dabao() # mc1.getCake() mc1()
5.__len__方法
触发时机:使用len函数检测对象的时候,自动触发
作用:使用len可以检测对象中某个数据的信息
参数:一个self,接收当前对象
返回值:必须要有,必须是整型
注意事项:无
# _author:"Ma ren" # date: 2023/2/25 # 声明一个类 class Car: # 成员属性 color = 'black' wight = '2t' grand = 'BYD' wheel = ['左前轮','右前轮','左后轮','右后轮','备胎'] # 成员方法 # 魔术方法 def __len__(self): print('__len__方法被触发') res = len(self.wheel) return res def playmusic(self): print('你存在我深深的脑海里') def move(self): print('请注意倒车,请注意倒车') # 实例化一个对象 car = Car() # 可以使用len函数检测对象吗? res = len(car) print(res)
触发时机:使用print打印对象的时候自动触发
作用:可以定义打印对象显示的信息内容
参数:一个self,接收当前对象
返回值:必须要有,必须是字符串类型
注意事项:除了print之外,使用str()转换数据的时候,也会触发
# _author:"Ma ren" # date: 2023/2/25 class Human: # 成员属性 color = 'yellow' gender = 'female' name = 'wuudd' age = 18 # 成员方法 # 魔法方法 def __str__(self): return self.name def eat(self): print('正向') def smile(self): print('hahhhahhah') l = list([1,2,3,4]) print(l) h = Human() print(h) # 触发__str__的第二个时机 str(h)
7.__repr__方法
触发时机:再使用repr转换对象的时候自动触发
作用:可以设置repr函数操作对象的结果
参数:一个self,接收当前对象
返回值:必须要有,必须是字符串类型
注意事项:正常情况下,类中的__str__和__repr__魔术方法是完全一致的.字符串中的str和repr方法是不一样的。
# _author:"Ma ren" # date: 2023/2/25 class Human: # 属性 color = 'yellow' name = 'egon' age = 18 gender = 'male' # 方法 # 魔术方法 在通常类中,repr方法重载相当于str方法被重载 def __repr__(self): print('__repr__方法被触发') # 所有类都默认存在一个等式 # __str__ = __repr__ # 将__repr__方法赋值给__str__方法,完全一样 def eat(self): print('真好吃') def drink(self): print('真好喝水') # h = Human() # print(h) # repr的使用 my_song = '我\n喜欢\t你' print(my_song) # 打印字符串对象 print(str(my_song)) print(repr(my_song))
触发时机:使用bool()转换对象的时候自动触发
作用:用户检测对象成员的信息
参数:一个self,接收当前对象
返回值:必须要有,必须是布尔值
注意事项:无
# _author:"Ma ren" # date: 2023/2/25 class Human: # 成员属性 name = 'tank' age = 18 gender = 'male' color = 'yellow' married = '未婚' # 成员方法 # 添加一个魔术方法__bool__ def __bool__(self): print('__bool__方法被触发') # 根据某些数据返回不同的布尔值,实现布尔转换对象的作用 if self.married == '已婚': return True else: return False def smoking(self): print('反向抽烟') def say(self): print('甜言蜜语') h = Human() print(h) # 转换对象 检测男人对象是否已婚 res = bool(h) print(res)
触发时机:使用bool()转换对象的时候自动触发
作用:用户检测对象成员的信息
参数:一个self,接收当前对象
返回值:必须要有,必须是布尔值
注意事项:无
# _author:"Ma ren" # date: 2023/2/25 class Girl: # 成员属性 name = '阿道夫' age = 18 gender = 'female' # 成员方法 # 添加魔术方法__format__ def __format__(self, format_spec): # print('__format__方法被触发') # print(format_spec) # format-spec接收的是限定符号的字符串 # return self.name # 实现format自带的对齐和填充功能 # 1.接收限定符号 flag = format_spec print(flag) # 2.拆分限定符号 fillchar = flag[0] # 填充字符 align = flag[1] # 对齐方式 length = int(flag[2:]) # 长度 print(fillchar,align,length) # 3.根据不同的符号进行不同的操作 # 判断对齐方式 if align == '>': # 右对齐 newname = self.name.rjust(length,fillchar) elif align == '^': # 居中对齐 newname = self.name.center(length,fillchar) elif align == '<': # 左对齐 newname = self.name.ljust(length,fillchar) return newname def shopping(self): print('买买买') def eating(self): print('吃吃吃') girl = Girl() print(girl) # 使用format来操作对象 action = '我和我的闺蜜{:@^20}去逛街' # res = action.format('静静') res = action.format(girl) print(res)
属性相关魔术方法
获取成员,删除成员,修改成员相关联的魔术方法
总共有5个
1.__getattr__
2.__setattr__
3.__delattr__
4.__getattribute__
5.__dir__
属性访问的顺序:
1.__getattribute__
2.调用数据描述符
3.调用当前对象的所属成员
4.调用类的所属成员
5.调用非数据描述符
6.调用父类的所属成员
7.调用__getattr__
注意:以上步骤就是调用某个成员的访问顺序及优先级,前面能够找到,就不会再向后查找
触发时机:访问对象成员的时候,就会触发,无论成员是否存在
作用:用户获取数据的时候,进行数据处理操作
参数:一个self,接收当前对象。参数item接收的是访问对象成员名称的字符串。
返回值:有,不设置返回值的时候,返回None
注意事项:在当前魔术方法中,禁止使用当前对象.成员的方式访问成员,否则会触发递归操作,必须借助object.__getattribute__来获取当前成员。
# _author:"Ma ren" # date: 2023/2/26 class Human: # 成员属性 def __init__(self): self.name = 'egon' self.gender = 'male' self.age = 18 # 成员方法 # 添加魔术方法 def __getattribute__(self, item): """ :param item: 所访问的成员属性名称 :return: """ # print('__getattribute__方法被触发') # print(item) # 注意,一定不能使用当前对象的成员访问,会再次触发当前魔术方法进入递归循环 res = object.__getattribute__(self,item) # 隐藏用户名 new_name = res[0] + '*' + res[-1] return new_name def eat(self): print('我是eat方法') def drink(self): print('我是drink方法') # 实例化对象 h = Human() print(h) # 访问对象的名称 print(h.name)
触发时机:访问不存在的对象成员的时候自动触发
作用:防止访问不存在的成员的时候报错!为不存在的成员定义值
参数:self,接收当前对象,第二个参数item,接收的是访问成员的名称字符串
返回值:可有可无,不设置返回值的时候,返回None
注意事项:在当前魔术方法中,禁止使用当前对象.成员的方式访问成员,否则会触发递归操作,必须借助object.__getattribute__来获取当前成员。
# _author:"Ma ren" # date: 2023/2/26 class Human: def __init__(self): self.name = 'takn' self.gender = 'male' self.age = 18 # 成员方法 # 添加魔术方法 def __getattr__(self, item): print('__getattr__被触发') print(item) return 4444 def eat(self): print('eat方法') def drink(self): print('drink方法') h = Human() # print(h) # print(h.gender) print(h.gender1)
12.__setattr__方法
触发时机:添加对象成员或者修改对象成员的时候自动触发
作用:可以限制或者管理对象的添加与修改操作
参数:self,接收当前对象,第二个参数key,接收的是访问成员的名称字符串,第三个参数value,是设置或者添加的成员的值对应的字符串
返回值:无
注意事项:在当前魔术方法中,禁止使用 当前对象.成员 的方式访问成员,否则会触发递归操作,必须借助object.__setattr__来获取当前成员。
# _author:"Ma ren" # date: 2023/2/26 class Human: def __init__(self): self.name = 'tnk' self.gender = 'male' self.age = 18 # 成员方法 # 魔术方法 def __setattr__(self, key, value): # 相当于在重载object中的__setattr__方法 # print(key,value) # 禁止修改性别,名称最多3个字符 # super.__setattr__(self,key,value) if key == 'gender': pass elif key == 'name': if len(value) > 3: pass else: object.__setattr__(self,key,value) else: object.__setattr__(self,key,value) # print('__setattr__被触发') def eat(self): print('eat方法') def drink(self): print('drink方法') h = Human() print(h.__dict__) # 修改对象成员 h.name = 'egon' print(h.__dict__)