Python-数据类之dataclasses

Python 中的 dataclass

dataclass 是 Python 3.7 引入的一个装饰器,用于简化类的定义,特别适合那些主要用于存储数据的类。它会自动为类生成一些常见的特殊方法,如 __init____repr____eq__ 等,从而减少样板代码的编写。



1. 基本用法

from dataclasses import dataclass

@dataclass
class Person:
    name: str
    age: int
    is_active: bool = True  # 默认值

# 创建实例
p = Person(name="Alice", age=30)

# 自动生成的 __repr__ 方法
print(p)  # 输出: Person(name='Alice', age=30, is_active=True)

# 修改属性
p.age = 31

# 比较两个实例(自动生成的 __eq__ 方法)
p2 = Person(name="Alice", age=31)
print(p == p2)  # 输出: True


2. 默认值和字段选项

默认值

字段可以设置默认值,或使用 field() 提供更高级的配置。

from dataclasses import dataclass, field

@dataclass
class Product:
    name: str
    price: float
    tags: list[str] = field(default_factory=list)  # 使用 `default_factory`

product = Product(name="Laptop", price=1000.0)
print(product)  # 输出: Product(name='Laptop', price=1000.0, tags=[])

default_factory

  • 用于创建默认值(如列表、字典),避免所有实例共享同一个对象。


3. 数据类字段的排序和比较

默认情况下,dataclass 的实例支持比较(如 <> 等),但需要设置 order=True

from dataclasses import dataclass

@dataclass(order=True)
class Item:
    price: float
    name: str

item1 = Item(price=10.0, name="Apple")
item2 = Item(price=20.0, name="Banana")

print(item1 < item2)  # 输出: True
  • order=True 会基于字段定义的顺序生成比较方法。


4. 忽略特定字段

使用 field() 可以跳过某些字段的比较或生成默认方法。

from dataclasses import dataclass, field

@dataclass
class Config:
    username: str
    password: str = field(repr=False)  # 在 __repr__ 中隐藏
    api_key: str = field(compare=False)  # 不用于比较

config1 = Config(username="admin", password="1234", api_key="abcd")
config2 = Config(username="admin", password="1234", api_key="xyz")
print(config1)  # 输出: Config(username='admin')
print(config1 == config2)  # 输出: True


5. 可变性(冻结模式)

通过设置 frozen=True,可以将数据类的实例变为不可变对象。

from dataclasses import dataclass

@dataclass(frozen=True)
class Point:
    x: int
    y: int

p = Point(1, 2)
# p.x = 3  # 会报错:FrozenInstanceError: cannot assign to field 'x'


6. 自定义方法

数据类可以定义自己的方法,与普通类无异。

from dataclasses import dataclass

@dataclass
class Rectangle:
    width: float
    height: float

    def area(self) -> float:
        return self.width * self.height

rect = Rectangle(width=5.0, height=10.0)
print(rect.area())  # 输出: 50.0


7. 数据类与字典互转

数据类转字典

使用 asdict 方法将数据类实例转换为字典。

from dataclasses import dataclass, asdict

@dataclass
class User:
    id: int
    name: str

u = User(id=1, name="Alice")
print(asdict(u))  # 输出: {'id': 1, 'name': 'Alice'}

字典转数据类

使用 from_dict(需安装 dacite 库)。

pip install dacite
from dataclasses import dataclass
from dacite import from_dict

@dataclass
class User:
    id: int
    name: str

data = {'id': 1, 'name': 'Alice'}
u = from_dict(data_class=User, data=data)
print(u)  # 输出: User(id=1, name='Alice')


总结

dataclass 是用于快速定义数据容器类的强大工具,其优点包括:

  1. 自动生成常用方法(__init____repr__ 等)。
  2. 支持字段默认值和默认工厂。
  3. 支持字段比较和排序。
  4. 可定义为不可变类。
  5. 提高代码可读性,减少样板代码。

对于需要大量数据存储的类,dataclass 是一个非常高效的选择!

文章标签:

评论(0)