Python魔术方法

一、常用魔术方法

特点:不需要人工调用,在特定的时刻自动执行.

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)

输出结果:

东方不败
西门吹雪

你可能感兴趣的:(#,Python基础,python,开发语言)