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__
# 输出:学生姓名:小红,年龄:17

2.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)) # 4

4.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])  # 输出 30

4.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__ 才能对比属性

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐