• 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__)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    输出结果:

    {‘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)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    输出结果:

    None

    3.__ del __:析构方法

    • 触发时机:对象被系统回收的时候自动触发(del不一定触发)
    • 作用:回收程序使用过程的信息和变量等,在操作数据库的时候最终关闭数据库
    • 参数:一个self接收当前对象
    • 返回值:无
    • 注意事项:无
      代码:
    class Human:
        def __del__(self):
            print('del方法被触发了')
    
    if __name__=='__main__':
        # 创建一个对象
        one=Human()
        # 输出对象的成员
        print(one)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    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('张三')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    输出结果:

    和面
    发酵
    烘焙
    切形状
    放水果
    给张三做的蛋糕已经完成

    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)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    输出结果:

    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)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    输出结果:

    史珍香

    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))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    输出结果:

    str被触发
    repr方法被触发
    史珍香

    str和repr的区别:

    mysong='我\n喜欢\t你'
    print(mysong)
    print(str(mysong))
    print(repr(mysong))
    
    • 1
    • 2
    • 3
    • 4

    输出结果:


    喜欢 你

    喜欢 你
    ‘我\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))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    输出结果:

    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))
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    输出结果:

    限定符号: @>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)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    输出结果:

    李*斯

    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)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    输出结果:

    访问成员变量不存在

    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)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    输出结果:

    东方不败
    西门吹雪

  • 相关阅读:
    到底什么是类脑计算?
    如何写考勤分析报告?
    BIGEMAP在土地规划中的应用
    在照片上添加水印怎么弄?三个简单方法分享给你
    为什么md5不可逆,却还可能被md5免费解密网站解密
    介绍下我的知识星球
    k8s--基础--08--环境搭建--安装kubernetes的web ui界面
    javascript数据类型
    8张图带你全面了解kafka的核心机制
    4G网络广播模块 4G网络广播开发模块
  • 原文地址:https://blog.csdn.net/qq_35653657/article/details/126003719