简述
在 Python 编程中,一些类用于存储数据,称为“数据类”,如商品模型。
attrs 是 Hynek Schlawack 设计的库,用于简化数据类定义。
dataclasses 是 Python 3.7 标准库模块,类似 attrs。
数据类的痛点
数据类常需实现:
__init__
初始化参数;__repr__
表示对象;__eq__
和比较方法;__hash__
用于去重;- to_dict 或 to_json 方法打包属性。
这些实现繁琐,希望有便捷方式定义参数和方法。
attrs
安装
pip install attrs
基本使用
import attr
@attr.s(hash=True)
class Product:
id = attr.ib()
author_id = attr.ib()
brand_id = attr.ib()
spu_id = attr.ib()
title = attr.ib(repr=False, cmp=False, hash=False)
item_id = attr.ib(repr=False, cmp=False, hash=False)
n_comments = attr.ib(repr=False, cmp=False, hash=False)
creation_time = attr.ib(repr=False, cmp=False, hash=False)
update_time = attr.ib(repr=False, cmp=False, hash=False)
source = attr.ib(default='', repr=False, cmp=False, hash=False)
parent_id = attr.ib(default=0, repr=False, cmp=False, hash=False)
ancestor_id = attr.ib(default=0, repr=False, cmp=False, hash=False)
@attr.s
设置全局选项,默认参数参与 repr、cmp、init,不参与 hash。
attr.ib
设置字段选项,优先级高。
示例中,所有字段在 init,前 4 个参与 repr、cmp、hash,后 3 个有默认值。
字段类型验证
用装饰器添加验证:
import attr
@attr.s
class C:
x = attr.ib()
@x.validator
def check(self, attribute, value):
if value > 42:
raise ValueError("x must be <= 42")
或用 validator 参数:
def x_smaller_than_y(instance, attribute, value):
if value >= instance.y:
raise ValueError("'x' must be < 'y'")
@attr.s
class C:
x = attr.ib(validator=[attr.validators.instance_of(int), x_smaller_than_y])
y = attr.ib()
先验证 x 为 int,再 x < y。
属性类型转化
自动转化类型:
import attr
@attr.s
class C:
x = attr.ib(converter=int)
传入 x 自动转为 int。
包含元数据
字段可含元数据:
@attr.s
class C:
x = attr.ib(metadata={'my_metadata': 1})
# 访问
attr.fields(C).x.metadata['my_metadata'] # 1
dataclasses
Python 3.7 新增,基于 PEP 557。Python 3.6 可 pip 安装。
示例:
from dataclasses import dataclass, field
from datetime import datetime
@dataclass(hash=True, order=True)
class Product:
id: int
author_id: int
brand_id: int
spu_id: int
title: str = field(hash=False, repr=False, compare=False)
item_id: int = field(hash=False, repr=False, compare=False)
n_comments: int = field(hash=False, repr=False, compare=False)
creation_time: datetime = field(default=None, repr=False, compare=False, hash=False)
update_time: datetime = field(default=None, repr=False, compare=False, hash=False)
source: str = field(default='', repr=False, compare=False, hash=False)
parent_id: int = field(default=0, repr=False, compare=False, hash=False)
ancestor_id: int = field(default=0, repr=False, compare=False, hash=False)
@dataclass
全局设置,默认参与 init、repr、eq,不参与 order、unsafe_hash。
field
设置字段选项。
用 type annotations 验证类型。