第64集:魔术方法基础
学习目标
- 理解魔术方法(特殊方法)的概念与作用
- 掌握魔术方法的命名规则(
__方法名__) - 学会常用的对象生命周期魔术方法
- 了解魔术方法如何让自定义类更好地融入 Python 生态
- 初步具备使用魔术方法增强类功能的能力
1. 什么是魔术方法
魔术方法(Magic Methods / Special Methods)是 Python 中以双下划线 __ 包围的特殊方法,例如 __init__、__str__、__len__ 等。
它们在特定场景下会被 Python 自动调用,使我们能够自定义类的行为,让它表现得像内置类型(如列表、字符串、数字等)。
1.1 魔术方法的特点
- 方法名前后都有双下划线
__xxx__ - 一般由 Python 解释器在特定操作时自动调用,无需手动调用
- 可以实现运算符重载、对象转换、容器行为等
2. 常见的对象生命周期魔术方法
2.1 __init__ —— 构造方法
在创建对象时初始化实例属性。
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
p = Person("Alice", 30) # 自动调用 __init__2.2 __del__ —— 析构方法
对象被销毁时调用,用于释放资源。
class FileHandler:
def __init__(self, filename):
self.file = open(filename, 'w')
def __del__(self):
self.file.close()
print("文件已关闭")2.3 __repr__ 与 __str__
__repr__:面向开发者的字符串表示,通常用于调试。repr(obj)或交互模式中直接输出对象时调用。__str__:面向用户的字符串表示,print(obj)或str(obj)时调用。
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __repr__(self):
return f"Point({self.x}, {self.y})"
def __str__(self):
return f"({self.x}, {self.y})"
p = Point(3, 4)
print(repr(p)) # Point(3, 4)
print(str(p)) # (3, 4)
print(p) # (3, 4) (调用 __str__)3. 布尔值与真值测试
3.1 __bool__
决定对象在布尔上下文(如 if obj:)中的真假。
如果没有定义 __bool__,Python 会尝试调用 __len__,若也没有则默认为 True。
class MyCollection:
def __init__(self, data):
self.data = data
def __bool__(self):
return len(self.data) > 0
col1 = MyCollection([1, 2, 3])
col2 = MyCollection([])
print(bool(col1)) # True
print(bool(col2)) # False4. 容器行为魔术方法(基础)
可以让类表现得像列表、字典等容器。
4.1 __len__
定义 len(obj) 的返回值。
class Bag:
def __init__(self, items):
self.items = items
def __len__(self):
return len(self.items)
bag = Bag([1, 2, 3])
print(len(bag)) # 34.2 __getitem__ 与 __setitem__
支持下标访问和赋值。
class SimpleList:
def __init__(self, items):
self.items = items
def __getitem__(self, index):
return self.items[index]
def __setitem__(self, index, value):
self.items[index] = value
sl = SimpleList([10, 20, 30])
print(sl[1]) # 20
sl[1] = 99
print(sl[1]) # 995. 实际应用案例:自定义数值向量
class Vector:
def __init__(self, *components):
self.components = list(components)
def __len__(self):
return len(self.components)
def __getitem__(self, index):
return self.components[index]
def __repr__(self):
return f"Vector{ tuple(self.components) }"
def __bool__(self):
return any(self.components) # 任一分量非零即为 True
v = Vector(0, 5, 0)
print(v) # Vector(0, 5, 0)
print(len(v)) # 3
print(bool(v)) # True6. 常见错误与注意事项
- 魔术方法必须严格使用双下划线包围,拼写错误会导致方法不被调用
__init__不应有返回值(返回非 None 会报错)__repr__应尽量返回一个有效的 Python 表达式字符串,便于调试- 如果定义了
__bool__,不要再依赖__len__来决定真值,避免逻辑混乱
7. 课后练习
- 为
Rectangle类实现__str__和__repr__,使打印和交互模式输出更直观。 - 为自定义的
Stack类实现__len__和__bool__,支持len(stack)与if stack:判断。 - 设计一个
Table类,实现__getitem__支持下标访问行数据。
总结
- 魔术方法是 Python 面向对象的重要特性,能显著增强类的功能和可用性
- 常用基础魔术方法包括构造/析构、字符串表示、布尔值、容器行为等
- 正确使用魔术方法可以让自定义类自然地融入 Python 语法和习惯用法
下一集我们将深入学习 常用魔术方法,掌握更多运算符重载与特殊功能的实现。