小白学 Python
课程GitHub
© 2026 小白学 Python · 基于 walter201230/Python 教程
课程目录GitHub
Python 环境加载中…
魔法方法0 / 5
12345

魔法方法

5 道练习题·预计 35 分钟·做对一题解锁下一段

教学 01 / 05· 已读

第一节:魔法方法

在 Python 中,所有以双下划线 __ 包起来的方法,都统称为 魔法方法(Magic Methods),也叫 魔术方法 / dunder 方法(dunder = double underscore)。

最常见的就是我们在上一章见过的 __init__。它在创建对象时自动被调用——你从来没有手动写过 obj.__init__(...),但它就是会跑。

魔法方法的能力远不止 __init__。它能让你自定义 Python 内置语法对你的对象的行为,比如:

写法背后调用的魔法方法
print(obj) / str(obj)__str__
obj1 == obj2__eq__
len(obj)__len__
obj[0]__getitem__
obj1 + obj2__add__

一句话:魔法方法 = 把你自己定义的类,接入 Python 内置语法。

列出一个类的魔法方法

任意一个类(哪怕一个空类)都已经从 object 继承了一堆魔法方法。用 dir() 可以查看:

python
class User:
    pass

print(dir(User()))

输出(截取一部分):

['__class__', '__delattr__', '__dict__', '__dir__', '__eq__', '__format__',
 '__getattribute__', '__hash__', '__init__', '__lt__', '__new__', '__repr__',
 '__setattr__', '__str__', ...]

可以看到,魔法方法非常多。本节我们挑最常用的几个学透——__str__ / __repr__、__eq__、__len__ / __getitem__、__add__。学完这几个,你写出的类就有了「Python 风味」。

教学 02 / 05

二、__str__ 与 __repr__:让 print 输出友好

先看一个问题。我们写一个最普通的 Book 类:

python
class Book:
    def __init__(self, title):
        self.title = title

b = Book('Python 入门')
print(b)

输出是什么?

<__main__.Book object at 0x10a9f3d50>

一串 ✗ 的乱码。这是因为默认情况下,print(obj) 会调用 object 的 __str__,它只会告诉你「这是一个 Book 对象,地址是 0x...」——对人类来说毫无信息量。

1、__str__:给「人」看的字符串

我们来重写它:

python
class Book:
    def __init__(self, title):
        self.title = title

    def __str__(self):
        return f'《{self.title}》'

b = Book('Python 入门')
print(b)         # 《Python 入门》
print(str(b))    # 《Python 入门》

__str__ 必须返回一个字符串。print(obj) 和 str(obj) 都会调用它。

2、__repr__:给「程序员」看的字符串

__repr__ 也是返回字符串,但用途不同:它通常是面向开发者的、最好能复现这个对象的写法。

最典型的场景是:在交互式终端里直接敲变量名,或者把对象放进 list 后 print:

python
class Book:
    def __init__(self, title):
        self.title = title

    def __str__(self):
        return f'《{self.title}》'

    def __repr__(self):
        return f"Book(title={self.title!r})"

b = Book('Python 入门')
print(b)        # 《Python 入门》  ← 走 __str__
print([b])      # [Book(title='Python 入门')]  ← 容器里走 __repr__

注意:

  • 如果只定义了 __repr__、没定义 __str__,那 print(obj) 会回退到 __repr__
  • 反过来不会——只定义 __str__ 时,[obj] 仍然显示默认的乱码

经验法则:至少先把 __repr__ 写了。再考虑要不要加更友好的 __str__。

练习 1 / 5·用 __str__ 让 print 输出友好题目有问题?

请定义类 Book:

  • __init__ 接收 title,保存到 self.title
  • __str__ 返回字符串 f'《{self.title}》'

然后实例化 Book('Python 入门') 赋给 b,并 print(b)。

输出应该是:

《Python 入门》
main.py
可编辑
🔒做对当前题解锁下一段 ·0/5
本章目录

魔法方法

  1. 教学 01第一节:魔法方法
  2. 教学 02二、`__str__` 与 `__repr__`:让 print 输出友好
  3. 练习 1用 __str__ 让 print 输出友好
  4. 教学 03三、`__eq__`:自定义「相等」的含义
  5. 练习 3 🔒用 __eq__ 自定义相等
  6. 教学 04四、`__len__` 与 `__getitem__`:让对象「像容器」
  7. 练习 2 🔒用 __len__ 让 len() 工作
  8. 练习 4 🔒用 __getitem__ 让对象支持下标
  9. 教学 05五、`__add__`:让对象支持 `+` 运算
  10. 练习 5 🔒用 __add__ 让对象支持 +
← 上一章09 · 模块
魔法方法
下一章 →11 · 枚举类