Python数据类实战:5个高效替代传统类的技巧
1. 基础数据类定义
替代传统类定义方式:
from dataclasses import dataclass
# 传统类定义
class PointOld:
def __init__(self, x: float, y: float):
self.x = x
self.y = y
def __repr__(self):
return f"PointOld(x={self.x}, y={self.y})"
# 数据类定义
@dataclass
class Point:
x: float
y: float
# 使用对比
p1 = PointOld(1.5, 2.5) # 传统方式
p2 = Point(1.5, 2.5) # 数据类方式
print(p1) # 需要手动实现__repr__
print(p2) # 自动生成__repr__
2. 默认值与类型提示
定义带默认值的字段:
from dataclasses import field
from typing import List
@dataclass
class User:
name: str
age: int = 18 # 带默认值的字段
hobbies: List[str] = field(default_factory=list) # 可变默认值
def greet(self):
return f"Hello, I'm {self.name}, {self.age} years old"
# 使用示例
user1 = User("Alice")
user2 = User("Bob", 25, ["reading", "swimming"])
print(user1.greet())
print(user2)
3. 不可变数据类
创建不可变实例:
@dataclass(frozen=True)
class ImmutablePoint:
x: float
y: float
def distance(self, other):
return ((self.x - other.x) ** 2 + (self.y - other.y) ** 2) ** 0.5
p1 = ImmutablePoint(1.0, 2.0)
p2 = ImmutablePoint(4.0, 6.0)
print(p1.distance(p2)) # 5.0
# p1.x = 3.0 # 会抛出FrozenInstanceError
4. 后初始化处理
使用__post_init__
方法:
@dataclass
class Rectangle:
width: float
height: float
area: float = field(init=False) # 不包含在__init__中
def __post_init__(self):
self.area = self.width * self.height
rect = Rectangle(3.0, 4.0)
print(rect) # Rectangle(width=3.0, height=4.0, area=12.0)
特性 | 传统类 | 数据类 |
---|---|---|
代码量 | 多(需手动实现) | 少(自动生成) |
可读性 | 依赖实现 | 高(结构清晰) |
功能完整性 | 需手动添加 | 默认提供 |
5. 高级应用:数据类继承
实现数据类继承关系:
@dataclass
class Person:
name: str
age: int
@dataclass
class Employee(Person):
employee_id: str
department: str
salary: float = field(default=5000.0, repr=False) # 不显示在repr中
# 使用示例
emp = Employee("Alice", 30, "E1001", "Engineering", 7500.0)
print(emp) # Employee(name='Alice', age=30, employee_id='E1001', department='Engineering')
合理使用数据类可以大幅减少Python中的样板代码,使你的代码更加简洁、易读且易于维护,特别适合数据密集型的应用场景。