在Python中,特殊类(通常指包含特殊方法的类)是实现面向对象编程和操作符重载的核心。这些特殊方法以双下划线开头和结尾(如 __init__),让自定义类能够与Python内置功能无缝集成。
核心特殊方法分类
1. 构造与析构方法
class MyClass:
def __new__(cls, *args, **kwargs):
"""创建实例时第一个调用的方法,返回实例对象"""
instance = super().__new__(cls)
return instance
def __init__(self, value):
"""初始化实例属性"""
self.value = value
print(f"初始化完成,值为: {value}")
def __del__(self):
"""对象被销毁时调用"""
print(f"对象 {self} 被销毁")2. 字符串表示方法
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
"""用户友好的字符串表示"""
return f"Person(name={self.name}, age={self.age})"
def __repr__(self):
"""开发者友好的字符串表示,通常可用于重建对象"""
return f"Person('{self.name}', {self.age})"
def __format__(self, format_spec):
"""支持格式化输出"""
if format_spec == "verbose":
return f"{self.name} is {self.age} years old"
return str(self)
# 使用示例
p = Person("Alice", 30)
print(str(p)) # Person(name=Alice, age=30)
print(repr(p)) # Person('Alice', 30)
print(f"{p:verbose}") # Alice is 30 years old3. 比较操作符重载
class Vector:
def __init__(self, x, y):
self.x = x
self.y = y
def __eq__(self, other):
"""等于 == """
if not isinstance(other, Vector):
return False
return self.x == other.x and self.y == other.y
def __lt__(self, other):
"""小于 < (基于向量长度)"""
if not isinstance(other, Vector):
return NotImplemented
return (self.x**2 + self.y**2) < (other.x**2 + other.y**2)
def __le__(self, other):
"""小于等于 <="""
return self < other or self == other
# 类似地可以定义 __gt__, __ge__, __ne__
# 使用示例
v1 = Vector(1, 2)
v2 = Vector(3, 4)
print(v1 == v2) # False
print(v1 < v2) # True4. 算术操作符重载
class ComplexNumber:
def __init__(self, real, imag):
self.real = real
self.imag = imag
def __add__(self, other):
"""加法 + """
if isinstance(other, ComplexNumber):
return ComplexNumber(self.real + other.real,
self.imag + other.imag)
return ComplexNumber(self.real + other, self.imag)
def __sub__(self, other):
"""减法 - """
if isinstance(other, ComplexNumber):
return ComplexNumber(self.real - other.real,
self.imag - other.imag)
return ComplexNumber(self.real - other, self.imag)
def __mul__(self, other):
"""乘法 * """
if isinstance(other, ComplexNumber):
real = self.real * other.real - self.imag * other.imag
imag = self.real * other.imag + self.imag * other.real
return ComplexNumber(real, imag)
return ComplexNumber(self.real * other, self.imag * other)
def __radd__(self, other):
"""右侧加法,处理 other + self 的情况"""
return self + other
# 使用示例
c1 = ComplexNumber(1, 2)
c2 = ComplexNumber(3, 4)
print((c1 + c2).real, (c1 + c2).imag) # 4, 65. 容器类方法
class CustomList:
def __init__(self, *args):
self._data = list(args)
def __getitem__(self, index):
"""获取元素 list[index]"""
return self._data[index]
def __setitem__(self, index, value):
"""设置元素 list[index] = value"""
self._data[index] = value
def __delitem__(self, index):
"""删除元素 del list[index]"""
del self._data[index]
def __len__(self):
"""返回长度 len(list)"""
return len(self._data)
def __contains__(self, item):
"""检查包含关系 item in list"""
return item in self._data
def __iter__(self):
"""返回迭代器"""
return iter(self._data)
# 使用示例
cl = CustomList(1, 2, 3, 4, 5)
print(len(cl)) # 5
print(cl[2]) # 3
print(3 in cl) # True6. 可调用对象
class Adder:
def __init__(self, base):
self.base = base
def __call__(self, x):
"""使实例可以像函数一样调用"""
return self.base + x
# 使用示例
add5 = Adder(5)
print(add5(10)) # 157. 上下文管理器
class FileManager:
def __init__(self, filename, mode):
self.filename = filename
self.mode = mode
self.file = None
def __enter__(self):
"""进入上下文时调用"""
self.file = open(self.filename, self.mode)
return self.file
def __exit__(self, exc_type, exc_val, exc_tb):
"""退出上下文时调用"""
if self.file:
self.file.close()
if exc_type:
print(f"异常发生: {exc_type}")
return False # 不抑制异常
# 使用示例
with FileManager("test.txt", "w") as f:
f.write("Hello, World!")8. 属性访问控制
class ProtectedClass:
def __init__(self):
self._protected = "protected"
self.__private = "private"
def __getattribute__(self, name):
"""属性访问拦截"""
print(f"访问属性: {name}")
return super().__getattribute__(name)
def __setattr__(self, name, value):
"""属性设置拦截"""
print(f"设置属性: {name} = {value}")
super().__setattr__(name, value)
def __getattr__(self, name):
"""访问不存在的属性时调用"""
return f"属性 {name} 不存在"
# 使用示例
obj = ProtectedClass()
print(obj._protected) # 先打印"访问属性: _protected",然后返回"protected"
print(obj.nonexistent) # 返回"属性 nonexistent 不存在"实际应用示例:实现一个智能分数类
class Fraction:
"""实现分数运算的类"""
def __init__(self, numerator, denominator=1):
if denominator == 0:
raise ValueError("分母不能为零")
# 约分
gcd_val = self._gcd(abs(numerator), abs(denominator))
self.numerator = numerator // gcd_val
self.denominator = denominator // gcd_val
# 确保分母为正
if self.denominator < 0:
self.numerator = -self.numerator
self.denominator = -self.denominator
@staticmethod
def _gcd(a, b):
"""计算最大公约数"""
while b:
a, b = b, a % b
return a
def __add__(self, other):
if isinstance(other, int):
other = Fraction(other)
common_denominator = self.denominator * other.denominator
new_numerator = (self.numerator * other.denominator +
other.numerator * self.denominator)
return Fraction(new_numerator, common_denominator)
def __sub__(self, other):
if isinstance(other, int):
other = Fraction(other)
common_denominator = self.denominator * other.denominator
new_numerator = (self.numerator * other.denominator -
other.numerator * self.denominator)
return Fraction(new_numerator, common_denominator)
def __mul__(self, other):
if isinstance(other, int):
other = Fraction(other)
return Fraction(self.numerator * other.numerator,
self.denominator * other.denominator)
def __truediv__(self, other):
if isinstance(other, int):
other = Fraction(other)
return Fraction(self.numerator * other.denominator,
self.denominator * other.numerator)
def __eq__(self, other):
if isinstance(other, int):
other = Fraction(other)
return (self.numerator == other.numerator and
self.denominator == other.denominator)
def __str__(self):
if self.denominator == 1:
return str(self.numerator)
return f"{self.numerator}/{self.denominator}"
def __repr__(self):
return f"Fraction({self.numerator}, {self.denominator})"
# 使用示例
f1 = Fraction(1, 2)
f2 = Fraction(3, 4)
print(f1 + f2) # 5/4
print(f1 * f2) # 3/8
print(f1 == Fraction(2, 4)) # True最佳实践建议
- 保持一致性:重载操作符时,确保行为与内置类型一致
- 适当使用NotImplemented:当操作不支持时返回NotImplemented
- 考虑性能:特殊方法可能被频繁调用,应保持高效
- 文档化:为所有特殊方法提供清晰的文档说明
- 测试覆盖:确保所有特殊方法都经过充分测试
掌握这些特殊方法的使用,能够让你创建出更加Pythonic、功能强大的自定义类。
















