Python——魔术方法 1. 基础概念1.1 什么是魔术方法魔术方法是 Python 官方内置的特殊方法统一语法格式为前后双下划线包裹__xxx__是面向对象编程的核心底层语法。它无需开发者手动调用会在对应代码场景触发时自动执行专门用于改写自定义类的默认底层行为。1.2 为什么需要魔术方法Python 原生仅支持字符串、列表、数字等内置数据类型的打印、运算、下标取值、长度获取等操作。而我们自己定义的类对象默认不具备这些能力直接操作会报错。魔术方法的核心作用给自定义对象赋予原生语法能力通过重写对应魔术方法自定义对象可以像内置对象一样实现打印、加减运算、大小比较、下标操作、迭代等功能。2. 核心魔术方法2.1 __init__ 初始化方法触发时机实例化对象时自动触发作用给对象初始化属性赋值class Student: # 创建对象自动执行 def __init__(self, name, age): self.name name self.age age s Student(小明, 18) # 自动触发 __init__ print(s.name, s.age)2.2 __new__ 构造方法触发时机创建对象的第一步最先执行优先级高于 __init__核心作用向内存开辟空间、创建并返回空白对象执行顺序__new__ 先造对象 → __init__ 后赋值__new__系统默认实现不用自己写2.3 __str__ 打印对象方法触发时机print(对象) 时自动触发作用自定义打印对象的内容不再输出默认内存地址无 __str__原生默认效果→ 打印内存地址class Student: def __init__(self, name, age): self.name name self.age age # 没有重写 __str__ s Student(小红, 17) # 直接打印输出垃圾内存地址看不到属性数据 print(s) # 示例输出__main__.Student object at 0x0000023xxxxxxx有__str__class Student: def __init__(self, name, age): self.name name self.age age # 重写打印规则 def __str__(self): return f学生姓名{self.name}年龄{self.age} s Student(小红, 17) print(s) # 自动触发 __str__ # 输出学生姓名小红年龄172.4 __del__ 析构方法触发时机对象被销毁、程序结束、主动 del 删除时自动触发作用资源释放关闭文件、关闭链接class Demo: def __del__(self): print(对象被销毁了释放资源) d Demo() del d # 主动删除对象触发 __del__ print(程序结束)3. 运算符重载魔术方法默认情况下自定义类对象不支持任何数学运算直接对两个对象进行加减乘除会直接报错。运算符重载魔术方法作用重写运算底层规则让自定义对象支持 - * / 大小比较。3.1 算术运算符重载以__add__为例没有重写 __add__对象之间无法相加代码运行直接抛异常。class Person: def __init__(self, height): self.height height p1 Person(170) p2 Person(180) print(p1 p2) # 直接对象相加无重载 【必报错】 # TypeError: unsupported operand type(s) for : Person and Person有重载重写__add__→ 正常运行class Person: def __init__(self, height): self.height height # 重载加法运算自定义对象相加规则 def __add__(self, other): return self.height other.height p1 Person(170) p2 Person(180) print(重载后对象相加结果, p1 p2) # 自动触发 __add__3.2逻辑运算符重载以__gt__为例除数学运算外自定义对象默认也无法正常比较大小、判断相等需要重载对应魔术方法实现功能。class Person: def __init__(self, age): self.age age def __gt__(self, other): return self.age other.age p1 Person(20) p2 Person(18) print(p1 p2) # True对象默认用内存地址判断相等哪怕属性完全一致也判定为不相等重写 __eq__ 可实现按属性判等。__lt__适配小于号 比较__eq__自定义对象相等判断规则判断两个对象是否相等默认比内存地址重写可比属性4. 容器类魔术方法列表/字典行为模拟4.1 __len__ 长度len(对象) 自动触发必须返回数字class MyList: def __init__(self, data): self.data data def __len__(self): return len(self.data) obj MyList([1,2,3,4]) print(len(obj)) # 44.2 __getitem__ 取值 []对象[下标] 自动触发class MyList: def __init__(self): self.data [10, 20, 30] # 开启下标取值功能 def __getitem__(self, index): # index 就是你传入的下标 return self.data[index] obj MyList() print(obj[0]) # 自动触发 __getitem__输出 10 print(obj[1]) # 输出 20 print(obj[2]) # 输出 304.3 __setitem__ 赋值 []对象[下标] 值 自动触发class MyList: def __init__(self): self.arr [10,20,30] # 取值 def __getitem__(self, index): return self.arr[index] # 赋值 def __setitem__(self, index, value): self.arr[index] value m MyList() print(m[0]) # 10 m[1] 999 print(m.arr) # [10, 999, 30]5. 迭代/上下文魔术方法5.1 __iter__ 迭代器核心作用让自定义类对象支持for 循环遍历默认自定义对象无法被迭代重写 __iter__ 即可拥有列表、元组一样的遍历能力。触发时机对对象执行 for 循环迭代时自动触发使用规则__iter__ 需要返回可迭代对象通常配合 iter() 函数实现class MyList: def __init__(self): self.data [11, 22, 33, 44] # 开启对象迭代能力 def __iter__(self): # 返回可迭代对象 return iter(self.data) # 实例化对象 obj MyList() # 普通for循环遍历自动触发 __iter__ for item in obj: print(item)5.2 __enter__ / __exit__ 上下文管理器核心作用让自定义对象支持with 语句语法自动完成「资源开启 资源关闭」杜绝资源泄露文件、网络连接常用。触发时机__enter__进入 with 代码块时自动触发开启资源__exit__退出 with 代码块时自动触发关闭资源哪怕代码报错也会执行核心优势无需手动写关闭代码自动收尾安全性极高。class FileTool: # 进入with块自动执行开启资源 def __enter__(self): print(1. 自动开启资源打开文件) return self # 返回对象给as变量接收 # 退出with块自动执行关闭资源 def __exit__(self, exc_type, exc_val, exc_tb): print(2. 自动关闭资源关闭文件) # 无论代码是否报错都会执行收尾操作 def read_data(self): print(读取文件数据) # with语法运行 with FileTool() as tool: tool.read_data() print(执行文件操作逻辑) print(with代码块结束资源自动释放完毕)运行流程进入with触发__enter__ → 执行内部业务代码 → 退出with触发__exit__自动收尾场景文件读写、数据库连接、网络请求连接统一用上下文管理器自动释放资源。6. 魔术方法汇总魔术方法触发场景核心作用__init__创建对象初始化属性__new__创建对象最先执行开辟内存、造对象__str__print(对象)自定义打印内容__del__对象销毁释放资源__add__对象 对象加法重载__sub__对象 - 对象减法重载__gt__对象 对象大于比较__eq__对象 对象相等判断__len__len(对象)获取自定义长度__getitem__对象[x]下标取值__setitem__对象[x]y下标赋值魔术方法自动触发不用手动调用默认情况下 对比的是内存地址重写 __eq__ 才能对比属性