Python学习笔记-面向对象(魔术方法)

本文深入解析Python中的魔术方法,包括初始化、实例化、析构、字符串表示、比较运算、算术运算等,揭示这些特殊方法如何增强类的功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.4.4 魔术方法

魔术方法是一个类的特殊方法,由系统自动调用

  1. __init__(self):初始化方法

    触发时机: 初始化对象时触发(不是实例化触发,但是跟实例化在一个操作里)

    参数: 至少有一个self用来接收对象

    返回值:

    作用: 初始化对象的成员

    注意: 如果有 __new__(),则在 __new__() 触发后触发

  2. __new__(cls):实例化方法 类方法

    触发时机: 实例化对象时触发

    参数: 至少有一个cls用来接收当前类

    返回值: 必须返回一个对象实例 super(类名,self).__new__()object.__new__(cls)

    作用: 实例化对象(开辟内存空间)

    注意: 实例化对象是Object类底层实现,其他类继承了Object的 __new__() 才能实例化对象。先于 __init__() 触发

    class Cls:
        def __init__(self):
            print('Init')
        def __new__(cls):
            print('New')
            return object.__new__(cls)
    cls1 = Cls()
    ================================
    New      # __new__(cls)先于__init__(self)触发
    Init
    
  3. __slots__ = 元组或列表:限制对象属性

    仅允许向对象中添加元组中列出的属性

  4. __del__(self):析构方法

    触发时机: 当对象没有被任何变量引用的时候被触发

    参数: self

    返回值:

    作用: 销毁对象时回收资源

    注意: del不一定会触发当前方法,只有当前对象无任何变量引用时才会触发

    class Cls1:
        def __del__(self):
            print('DEL')
        def whiletrue(self,i):
            print('第{}次调用'.format(i))
    
    cls1 = Cls1()         # 创建一个对象cls1
    cls2 = cls1           # 让cls2引用cls1(内存地址是同一个)
    del cls1              # 删除cls1,此时无法再调用cls1
    for i in range(1,5):  # 调用whiletrue()方法4次
        cls2.whiletrue(i) # 最后一次调用结束后执行析构函数进行销毁
    ================================1次调用
    第2次调用
    第3次调用
    第4次调用
    DEL
    
  5. __len__() :

    触发时机: 使用 len(对象) 时触发

    参数: self

    返回值: 必须是一个整形

    作用: 可以设置为检测对象成员个数,也可以是其他方法

    注意: 返回值必须是整数

  6. __str__() :

    触发时机: 使用 str(对象)print(对象) 时触发

    参数: self

    返回值: 必须是字符串

    作用: print(对象)时进行操作,得到字符串,一般用于输出快捷信息

    class Cls1:
        def __str__(self):
            ss = 'this is __str__(self) return value'
            return ss
    cls1 = Cls1()
    print(cls1)
    ================================
    this is __str__(self) return value
    
  7. __repr__()

    触发时机: 使用 repr(对象) 时触发

    参数: self

    返回值: 必须是字符串

    作用: repr(对象)时进行操作,得到字符串,一般用于输出快捷信息

    __str__(self) 的区别是,一个用 print(对象) 直接调用,一个需要接收一下返回值再打印

    class Cls1:
        def __repr__(self):
            ss = 'this is __repr__(self) return value'
            return ss
    cls1 = Cls1()
    res = repr(cls1)
    print(res)
    ================================
    this is __repr__(self) return value
    
  8. __call__(self,*args,**kwargs)

    触发时机: 使用 对象(参数列表) 时触发

    参数: self,*args,**kwargs

    返回值: 不做规定

    作用: 把对象当函数用

    class Cls1:
        def __call__(self, *args, **kwargs):
            print('call!',args,kwargs)
    cls1 = Cls1()
    cls1(1,2,a=3,b=4)
    ================================
    call! (1, 2) {'a': 3, 'b': 4}
    
  9. __gt__ __lt__ __eq__ __ge__ __le__ __ne__系列:

    触发时机: 使用 对象1 比较运算符 对象2 时触发

    参数: self,other

    返回值: 布尔类型

    作用: 指定一个比较依据来比较对象

    注意: 一般而言定义一个即可,如果都定义了会自动找对应的方法

    class Cls1:
        def __init__(self, age):
            self.age = age
        def __gt__(self, other):   # 大于
            print('__gt__',end='')
            return self.age > other.age
        def __ge__(self, other):   # 大于等于
            print('__ge__',end='')
            return self.age >= other.age
        def __eq__(self, other):   # 等于
            print('__eq__',end='')
            return self.age == other.age
        def __le__(self, other):   # 小于等于
            print('__le__',end='')
            return self.age <= other.age
        def __lt__(self, other):   # 小于
            print('__lt__',end='')
            return self.age < other.age
        def __ne__(self, other):   # 不等于
            print('__ne__',end='')
            return self.age != other.age
    cls1 = Cls1(12)
    cls2 = Cls1(13)
    print(cls1.__eq__(cls2))   # 调用形式1 对象1.方法(对象2)
    print(cls1>cls2)           # 调用形式2 对象 比较运算符 对象2
    ================================
    __eq__False
    __gt__False
    
  10. 算术运算相关方法

    class cls1:
        def __add__(self, other):   # 定义加法行为
            pass
        def __sub__(self, other):   # 定义减法行为
            pass
        def __mul__(self, other):   # 定义乘法行为
            pass
        def __truediv__(self, other):   # 定义真除法行为
            pass
        def __floordiv__(self, other):   # 定义整除行为
            pass
        def __mod__(self, other):   # 定义取模行为
            pass
        def __divmod__(self, other):   # 定义当被divmod()调用时行为
            pass
        def __pow__(self, power, modulo=None):   # 定义被power()调用或乘方运算时行为
            pass
        def __lshift__(self, other):   # 定义按位左行为
            pass
        def __rshift__(self, other):   # 定义按位右行为
            pass
        def __and__(self, other):   # 定义按位与行为
            pass
        def __xor__(self, other):   # 定义按位异或行为
            pass
        def __or__(self, other):   # 定义按位或行为
            pass
    
  11. 反运算相关方法

    当左操作数不支持相应的操作时被调用

    class cls1:
        def __radd__(self, other):   # 定义加法行为
            pass
        def __rsub__(self, other):   # 定义减法行为
            pass
        def __rmul__(self, other):   # 定义乘法行为
            pass
        def __rtruediv__(self, other):   # 定义真除法行为
            pass
        def __rfloordiv__(self, other):   # 定义整除行为
            pass
        def __rmod__(self, other):   # 定义取模行为
            pass
        def __rdivmod__(self, other):   # 定义当被divmod()调用时行为
            pass
        def __rpow__(self, power, modulo=None):   # 定义被power()调用或乘方运算时行为
            pass
        def __rlshift__(self, other):   # 定义按位左行为
            pass
        def __rrshift__(self, other):   # 定义按位右行为
            pass
        def __rand__(self, other):   # 定义按位与行为
            pass
        def __rxor__(self, other):   # 定义按位异或行为
            pass
        def __ror__(self, other):   # 定义按位或行为
            pass
    
  12. 赋值相关方法

    class cls1:
        def __iadd__(self, other):   # 定义加法行为并赋值
            pass
        def __isub__(self, other):   # 定义减法行为并赋值
            pass
        def __imul__(self, other):   # 定义乘法行为并赋值
            pass
        def __itruediv__(self, other):   # 定义真除法行为并赋值
            pass
        def __ifloordiv__(self, other):   # 定义整除行为并赋值
            pass
        def __imod__(self, other):   # 定义取模行为并赋值
            pass
        def __ipow__(self, power, modulo=None):   # 定义被power()调用或乘方运算时行为并赋值
            pass
        def __ilshift__(self, other):   # 定义按位左行为并赋值
            pass
        def __irshift__(self, other):   # 定义按位右行为并赋值
            pass
        def __iand__(self, other):   # 定义按位与行为并赋值
            pass
        def __ixor__(self, other):   # 定义按位异或行为并赋值
            pass
        def __ior__(self, other):   # 定义按位或行为并赋值
            pass
    
  13. 一元运算相关方法

    class cls1:
        def __pos__(self):   # 定义正号行为
            pass
        def __neg__(self):   # 定义负号行为
            pass
        def __abs__(self):   # 定义当被abs()调用时行为
            pass
        def __invert__(self):   # 定义按位取反行为
            pass
    
  14. 类型转换相关方法

    class cls1:
        def __complex__(self):   # 定义当被complex()调用时的行为,需返回恰当值
            pass
        def __int__(self):   # 定义当被int()调用时的行为,需返回恰当值
            pass
        def __float__(self):   # 定义当被float()调用时的行为,需返回恰当值
            pass
        def __round__(self, n=None):   # 定义当被round()调用时的行为,需返回恰当值
            pass
        def __index__(self):   # 当对象是被应用在切片表达式中,实现整形强制类型转换
            pass               # 如果定义了一个可能在切片时用到的定制的数型值,则应该定义index
                               # 如果index被定义,则int也需要被定义,且返回相同的值
    
  15. 上下文管理相关方法(with)

    class cls1:
        def __enter__(self):
            '''
            定义当使用with语句时的初始化行为
            enter的返回值被with语句的目标或者as后的名字绑定
            '''
            pass
        def __exit__(self, exc_type, exc_val, exc_tb):
            '''
            定义当一个代码块被执行或者终止后上下文管理器应该做什么
            一般被用来处理异常,清除工作或者做一些代码块执行完毕后的日常工作
            '''
            pass
    
  16. 容器类型相关方法

    class cls1:
        def __len__(self):   # 定义当被len()调用时的行为(返回容器中元素的个数)
            pass
        def __getitem__(self, item):   # 定义获取容器中指定元素的行为,相当于self[key]
            pass
        def __setitem__(self, key, value): # 定义设置容器中指定元素的行为,相当于self[key]=value
            pass
        def __delitem__(self, key):   # 定义删除容器中指定元素的行为,相当于del self[key]
            pass
        def __iter__(self):   # 定义当迭代容器中的元素的行为
            pass
        def __reversed__(self):   # 定义当被reversed() 调用时的行为
            pass
        def __contains__(self, item):   # 定义当使用成员测试运算符(in 或not in)时的行为
            pass
    
  17. 与属性操作相关的方法

    __getattribute__()

    触发时机: 使用对象成员时触发,无论成员是否存在

    参数: self,获取成员名的字符串

    返回值: 必须有返回值

    作用: 在有封装操作(私有化)时,为程序开放部分权限使用

    __getattr__()

    触发时机: 获取不存在的对象成员时触发

    参数: self,获取成员名的字符串

    返回值: 必须返回一个值

    作用: 为访问不存在的属性设置值(可以理解为不报错的优雅提示)

    注意: __getattribute__() 无论如何都会在 __getattr__() 之前触发,__getattr__() 触发后不会再触发 __getattribute__()

    __setattr__()

    触发时机: 设置对象成员值时触发

    参数: self,获取成员名的字符串,要设置的值

    返回值: 过程操作,无返回值

    作用: 接管设置操作,可以在设置前做前置行为比如验证

    注意: 在当前方法中无法使用 成员=值 的方法直接设置成员,否则会 无限递归,必须借助 objece 来实现。比如 object.__setattr__(对象名,key,value)

    事实上,当执行 对象.属性 = 值 时,系统默认执行本来写好的 __setattr__() 方法,当在类中重写这个方法后,这个方法可能会失去赋值的能力,因此除了修改重写的方法外,还可以借助object的 __setattr__() 来实现赋值

    class Cls1:
        name = 'TEST'
        def __getattr__(self, item):   # 当调用一个不存在的属性时,提示该属性不存在
            return '属性:{}不存在'.format(item)
        def __setattr__(self, key, value):
            # self.__dict__[key] = value       # 使用self.__dict__[key] = value 实现赋值
            object.__setattr__(self,key,value) # 借助object实现赋值,与上面二选一即可
    cls1 = Cls1()
    cls1.name = 'ABC'
    print(cls1.name)
    ============================
    ABC
    
    class Cls1:
        name = 'TEST'
        def __getattr__(self, item):
            return '属性:{}不存在'.format(item)
        def __setattr__(self, key, value):
            pass         # 没有可供赋值的语句
    cls1 = Cls1()
    cls1.name = 'ABC'    # 对象.属性 = 值,调用__setattr__()时,里面无赋值语句,无法实现赋值
    print(cls1.name)
    object.__setattr__(cls1,'age',13)    # 借助object的__setattr__()实现赋值
    print(cls1.age)
    ============================
    TEST
    13
    

    __delattr__()

    触发时机: 删除对象成员时触发

    参数: self

    返回值: 过程操作,无返回值

    作用: 可以在删除成员前做前置行为比如验证

    __dir__()

    触发时机: dir(对象)时触发

    参数: self

    返回值: 必须是序列类型(列表,元组,集合等)

    作用: 自定义成员列表返回值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值