一、常用魔术方法
特点:不需要人工调用,在特定的时刻自动执行.
1.__ init __ :初始化魔术方法(最重要)
- 触发时机:实例化对象之后触发
- 作用:为对象添加所属成员
- 参数:一个self接受当前对象,其他的参数根据实例化的传参决定
- 返回值:无
- 注意事项:无
代码:
class Human:
def __init__(self,kindname,petname):
self.sex='男'
self.age=1
self.name=kindname
self.petname=petname
if __name__=='__main__':
# 创建一个对象
one=Human('刘佳琪','小妮子')
# 输出对象的成员
print(one.__dict__)
输出结果:
{'sex': '男', 'age': 1, 'name': '刘佳琪', 'petname': '小妮子'}
2.__ new __:构造方法
- 触发时机:实例化对象的时候触发
- 作用:管理控制对象的生成
- 参数:一个cls接收当前类,其他的参数根据实例化的参数决定
- 返回值:可有可无 没有返回值,实例化结果为None
- 注意事项:new 魔术方法跟init的魔术方法的参数一致(除了第一个)
代码:
class Human:
def __new__(cls, sex):
# 如果生女就返回对象,如果生男就不管
if sex=='女':
return object.__new__(cls)
else:
return None
if __name__=='__main__':
# 创建一个对象
one=Human('男')
# 输出对象的成员
print(one)
输出结果:
None
3.__ del __:析构方法
- 触发时机:对象被系统回收的时候自动触发(del不一定触发)
- 作用:回收程序使用过程的信息和变量等,在操作数据库的时候最终关闭数据库
- 参数:一个self接收当前对象
- 返回值:无
- 注意事项:无
代码:
class Human:
def __del__(self):
print('del方法被触发了')
if __name__=='__main__':
# 创建一个对象
one=Human()
# 输出对象的成员
print(one)
4.__ call __:
- 触发时机:将对象当做函数调用的时候自动触发
- 作用:常用于归结类/对象的操作步骤,方便后期调用
- 参数:一个self接收当前对象,其余的参数根据需求添加
- 返回值:可以有可以无
- 注意事项:无
代码:
class MakeCake:
def huomian(self):
print("和面")
def fajiao(self):
print('发酵')
def honbei(self):
print('烘焙')
def qiexinzhuan(self):
print('切形状')
def fangshuiguo(self):
print('放水果')
def __call__(self,name):
self.huomian()
self.fajiao()
self.honbei()
self.qiexinzhuan()
self.fangshuiguo()
print('给{}做的蛋糕已经完成'.format(name))
if __name__=='__main__':
cake=MakeCake()
cake('张三')
输出结果:
和面
发酵
烘焙
切形状
放水果
给张三做的蛋糕已经完成
5.__ len __:
- 触发时机:使用len函数检测对象的时候自动触发
- 作用:使用len可以检测对象中某个数据的信息
- 参数:一个self接收当前对象
- 返回值:必须有返回值,必须是整型
- 注意事项:len检测什么,由开发者自定定
代码:
class car:
# 成员属性
color='黑色'
weight='2T'
grand='奥利奥'
circle=['左前轮','右前轮','左后轮','右后轮','备胎']
# 成员方法
def playmusic(self):
print('你存在我深深的脑海')
def move(self):
print('请注意倒车,请注意倒车')
def __len__(self):
num=len(self.circle)
return num
# 实例化一个对象
mycar=car()
# 定义了len方法,就可以直接使用len计算这个类的长度
result=len(mycar)
print(result)
输出结果:
5
6.__ str __:
- 触发时机:使用print打印对象的时候自动触发
- 作用:可以定义打印对象显示的信息内容
- 参数:一个self接受当前对象
- 返回值:必须有,且必须是字符串
- 注意事项:除了print之外,使用str()转换数据的时候也会触发
代码:
class Human:
# 成员属性
color = '黄色'
sex = '女'
age = 18
name = '史珍香'
# 成员方法
def __str__(self):
# 重载魔术方法__str__(继承自object类)
return self.name
def eat(self):
print('真香~')
def smile(self):
print('哈哈哈哈哈')
if __name__ == '__main__':
wuman = Human()
# 第一种触发方式
print(wuman)
输出结果:
史珍香
7.__ repr __:
- 触发时机:在使用repr转换对象的时候自动触发
- 作用:可以设置repr函数操作对象的结果
- 参数:一个self接受当前对象本身
- 返回值:必须有,且必须是字符串
- 注意事项:在正常情况下repr和str魔术方法是完全一样的(字符串中的str和repr魔术方法就不一样)
代码:
class Human:
# 成员属性
color = '黄色'
sex = '女'
age = 18
name = '史珍香'
# 成员方法
# __repr__魔术方法,在通常的类中repr重载相当于str也被重载
def __repr__(self):
print('repr方法被触发')
return self.name
def __str__(self):
return 'str被触发'
# 所有类默认都存在一个等式
# __str__=__repr__ 将repr的方法赋值给str方法 完全一样
def eat(self):
print('真香~')
def smile(self):
print('哈哈哈哈哈')
human=Human()
print(human)
print(repr(human))
输出结果:
str被触发
repr方法被触发
史珍香
str和repr的区别:
mysong='我\n喜欢\t你'
print(mysong)
print(str(mysong))
print(repr(mysong))
输出结果:
我
喜欢 你
我
喜欢 你
'我\n喜欢\t你'
8.__ bool __:
- 触发时机:在使用bool()转换对象的时候自动触发
- 作用:用于检测对象成员的信息
- 参数:一个self接受当前对象
- 返回值:必须有,且必须是bool值
- 注意事项:任何对象在使用bool方法的时候默认都是True
代码:
class man:
sex='男'
age=18
married='已婚'
def __bool__(self):
print('bool方法已经被触发')
if self.married=='已婚':
return True
else:
return False
def smkoking(self):
print('多数男人都抽烟~')
def say(self):
print('男人都是甜言蜜语')
man=man()
print(bool(man))
输出结果:
bool方法已经被触发
True
9.__ format __:
- 触发时机:在使用format()转换对象的时候自动触发
- 作用:用于格式化输出信息
- 参数:一个self接受当前对象,arg接受格式
- 返回值:必须有,且必须为字符串格式
- 注意事项:可以不是格式,直接作为填充输出
代码:
class Girl:
# 成员属性
name='熊楮墨'
sex='女'
age=18
# 成员方法
def __format__(self,arg):
# arg是接受限定符号的字符串
# 1.接受限定符号
flag=arg
print('限定符号:',flag)
# 2.拆分限定符号
fillchar=flag[0] # 填充字符
align=flag[1] # 对齐方式
length=int(flag[2:]) # 字符长度
# 3.根据不同的符号进行不同的填充操作
# 判断对齐方式
if align=='>':# 右对齐
newname=self.name.rjust(length,fillchar)
return newname
elif align=='^':
newname=self.name.center(length.fillchar)
return newname
elif align=='<': # 左对齐
newname=self.name.ljust(length,fillchar)
return newname
def shopping(self):
print('买买买~~')
def eat(self):
print('吃烧烤~~')
# 实例化一个对象
girl=Girl()
action='我想和{:@>10}去逛街'
print(action.format(girl))
输出结果:
限定符号: @>10
我想和@@@@@@@熊楮墨去逛街
二、属性相关的魔术方法
就是获取成员,删除成员,修改成员相关联的魔术方法
5个属性相关的魔术方法:
- __ getattr __
- __ setattr __
- __ delattr __
- __ getattribute __
- __ dir __
属性访问的顺序!:
- 1.调用__ getattribute __
- 2.【调用数据描述符】
- 3.调用当前对象的所属成员
- 4.调用类的所属成员
- 5.【调用非数据描述符】
- 6.调用父类的所属成员
- 7.调用getattr
注意:以上步骤是调用某个成员的访问顺序以及优先级,前面的能获取成员,就不会向后查找
1.__ getattribute __
- 触发时机:访问对象成员的时候就会触发,无论成员是否存在
- 作用:可以在用户获取数据的时候进行数据处理等操作
- 参数:一个self接受当前对象,另外一个参数接受访问对象成员名称的字符串
- 返回值: 有 不设定返回None
- 注意事项:在当前魔术方法中禁止使用 当前对象.成员 的方式访问成员,会触发递归操作,必须借助object的getattribute来获取当前对象的成员变量
代码:
class Human:
# 添加成员属性(加入对象)
def __init__(self):
self.name='李斯'
self.sex='男'
self.age=18
# 添加成员方法
# 添加魔术方法__getattribute__
def __getattribute__(self, item):
# item接受的是访问成员的名称字符串
# 一定不能使用当前对象的成员访问,会再次触发当前魔术方法进入递归循环
result=object.__getattribute__(self,item)
# 隐藏用户名(自己的惭怍)
newname=result[0]+'*'+result[-1]
# 返回的数据
return newname
def eat(self):
print('一天三顿小烧烤')
def drink(self):
print('喝啤酒')
# 实例化对象
ls=Human()
print(ls.name)
输出结果:
李*斯
2.__ getattr __
- 触发时机:访问不存在对象成员的时候自动触发
- 作用:防止访问不存在的成员的时候报错!为不存在的成员定义值
- 参数:一个self接受当前对象,另外一个参数接受访问对象成员名称的字符串
- 返回值:可有可无
- 注意事项:无
代码:
class Human:
# 添加成员属性(加入对象)
def __init__(self):
self.name='李斯'
self.sex='男'
self.age=18
def __getattr__(self, item):
return '访问成员变量不存在'
def eat(self):
print('一天三顿小烧烤')
def drink(self):
print('喝啤酒')
# 实例化对象
ls=Human()
print(ls.name2)
输出结果:
访问成员变量不存在
3.setattr
- 触发时机:添加对象成员或者修改对象成员的时候自动触发
- 作用:可以限制或者管理对象成员的添加与修改操作
- 参数:一个self接受当前对象,第二个接受设置的成员变量名称字符串 第三个接受设置的值
- 返回值:无
- 注意事项:在当前魔术方法中禁止使用当前对象.成员名=值得方式,会触发递归操作!
代码:
class Human:
# 添加成员属性(加入对象)
def __init__(self):
self.name='东方不败'
self.sex='男'
self.age=18
def __setattr__(self, key, value):
# 这样可以设置性别不修改
if key=='sex':
object.__setattr__(self, key,'男')
else:
object.__setattr__(self,key,value)
def eat(self):
print('一天三顿小烧烤')
def drink(self):
print('喝啤酒')
# 实例化对象
ls=Human()
print(ls.name)
ls.name='西门吹雪'
ls.sex='女'
print(ls.name)
print(ls.sex)
输出结果:
东方不败
西门吹雪
男