Hub Python 库文档
严格数据类
并获得增强的文档体验
开始使用
严格数据类
huggingface_hub
包提供了一个用于创建**严格数据类**的实用工具。它们是 Python 标准 dataclass
的增强版本,具有额外的验证功能。严格数据类确保字段在初始化和赋值时都经过验证,这使得它们非常适合数据完整性至关重要的场景。
概述
严格数据类使用 @strict
装饰器创建。它们通过以下方式扩展了常规数据类的功能:
- 根据类型提示验证字段类型
- 支持自定义验证器以进行额外检查
- 可选地允许构造函数中的任意关键字参数
- 在初始化和赋值时都验证字段
优点
- 数据完整性:确保字段始终包含有效数据
- 易用性:与 Python 的
dataclass
模块无缝集成 - 灵活性:支持自定义验证器以实现复杂的验证逻辑
- 轻量级:无需 Pydantic、attrs 或类似库等额外依赖
用法
基本示例
from dataclasses import dataclass
from huggingface_hub.dataclasses import strict, as_validated_field
# Custom validator to ensure a value is positive
@as_validated_field
def positive_int(value: int):
if not value > 0:
raise ValueError(f"Value must be positive, got {value}")
@strict
@dataclass
class Config:
model_type: str
hidden_size: int = positive_int(default=16)
vocab_size: int = 32 # Default value
# Methods named `validate_xxx` are treated as class-wise validators
def validate_big_enough_vocab(self):
if self.vocab_size < self.hidden_size:
raise ValueError(f"vocab_size ({self.vocab_size}) must be greater than hidden_size ({self.hidden_size})")
字段在初始化期间进行验证
config = Config(model_type="bert", hidden_size=24) # Valid
config = Config(model_type="bert", hidden_size=-1) # Raises StrictDataclassFieldValidationError
字段之间的一致性也在初始化期间进行验证(类级验证)
# `vocab_size` too small compared to `hidden_size`
config = Config(model_type="bert", hidden_size=32, vocab_size=16) # Raises StrictDataclassClassValidationError
字段在赋值期间也进行验证
config.hidden_size = 512 # Valid
config.hidden_size = -1 # Raises StrictDataclassFieldValidationError
要在赋值后重新运行类级验证,必须显式调用 .validate
config.validate() # Runs all class validators
自定义验证器
您可以使用 validated_field
为字段附加多个自定义验证器。验证器是一个可调用对象,它接受一个参数并在值无效时引发异常。
from dataclasses import dataclass
from huggingface_hub.dataclasses import strict, validated_field
def multiple_of_64(value: int):
if value % 64 != 0:
raise ValueError(f"Value must be a multiple of 64, got {value}")
@strict
@dataclass
class Config:
hidden_size: int = validated_field(validator=[positive_int, multiple_of_64])
在此示例中,两个验证器都应用于 hidden_size
字段。
附加关键字参数
默认情况下,严格数据类只接受类中定义的字段。您可以通过在 @strict
装饰器中设置 accept_kwargs=True
来允许附加关键字参数。
from dataclasses import dataclass
from huggingface_hub.dataclasses import strict
@strict(accept_kwargs=True)
@dataclass
class ConfigWithKwargs:
model_type: str
vocab_size: int = 16
config = ConfigWithKwargs(model_type="bert", vocab_size=30000, extra_field="extra_value")
print(config) # ConfigWithKwargs(model_type='bert', vocab_size=30000, *extra_field='extra_value')
附加关键字参数会出现在数据类的字符串表示中,但会以 *
为前缀,以强调它们未经验证。
与类型提示集成
严格数据类尊重类型提示并自动验证它们。例如:
from typing import List
from dataclasses import dataclass
from huggingface_hub.dataclasses import strict
@strict
@dataclass
class Config:
layers: List[int]
config = Config(layers=[64, 128]) # Valid
config = Config(layers="not_a_list") # Raises StrictDataclassFieldValidationError
支持的类型包括
- 任意
- 联合
- 可选
- 字面量
- 列表
- 字典
- 元组
- 集合
以及这些类型的任意组合。如果您需要更复杂的类型验证,可以通过自定义验证器实现。
类验证器
名为 validate_xxx
的方法被视为类验证器。这些方法必须只接受 self
作为参数。类验证器在初始化期间运行一次,紧随 __post_init__
之后。您可以根据需要定义任意数量的类验证器——它们将按照出现的顺序依次执行。
请注意,当字段在初始化后更新时,类验证器不会自动重新运行。要手动重新验证对象,您需要调用 obj.validate()
。
from dataclasses import dataclass
from huggingface_hub.dataclasses import strict
@strict
@dataclass
class Config:
foo: str
foo_length: int
upper_case: bool = False
def validate_foo_length(self):
if len(self.foo) != self.foo_length:
raise ValueError(f"foo must be {self.foo_length} characters long, got {len(self.foo)}")
def validate_foo_casing(self):
if self.upper_case and self.foo.upper() != self.foo:
raise ValueError(f"foo must be uppercase, got {self.foo}")
config = Config(foo="bar", foo_length=3) # ok
config.upper_case = True
config.validate() # Raises StrictDataclassClassValidationError
Config(foo="abcd", foo_length=3) # Raises StrictDataclassFieldValidationError
Config(foo="Bar", foo_length=3, upper_case=True) # Raises StrictDataclassFieldValidationError
方法 .validate()
是严格数据类中的保留名称。为防止意外行为,如果您的类已经定义了此方法,将引发 StrictDataclassDefinitionError
错误。
API 参考
@strict
@strict
装饰器通过严格验证增强了数据类。
huggingface_hub.dataclasses.strict
< 源 >( accept_kwargs: bool = False )
用于为数据类添加严格验证的装饰器。
此装饰器必须在 @dataclass
之上使用,以确保 IDE 和静态类型工具将该类识别为数据类。
可以带参数或不带参数使用
@strict
@strict(accept_kwargs=True)
示例
>>> from dataclasses import dataclass
>>> from huggingface_hub.dataclasses import as_validated_field, strict, validated_field
>>> @as_validated_field
>>> def positive_int(value: int):
... if not value >= 0:
... raise ValueError(f"Value must be positive, got {value}")
>>> @strict(accept_kwargs=True)
... @dataclass
... class User:
... name: str
... age: int = positive_int(default=10)
# Initialize
>>> User(name="John")
User(name='John', age=10)
# Extra kwargs are accepted
>>> User(name="John", age=30, lastname="Doe")
User(name='John', age=30, *lastname='Doe')
# Invalid type => raises
>>> User(name="John", age="30")
huggingface_hub.errors.StrictDataclassFieldValidationError: Validation error for field 'age':
TypeError: Field 'age' expected int, got str (value: '30')
# Invalid value => raises
>>> User(name="John", age=-1)
huggingface_hub.errors.StrictDataclassFieldValidationError: Validation error for field 'age':
ValueError: Value must be positive, got -1
as_validated_field
用于创建 validated_field
的装饰器。建议用于只有一个验证器的字段,以避免样板代码。
huggingface_hub.dataclasses.as_validated_field
< 源 >( validator: typing.Callable[[typing.Any], NoneType] )
将验证器函数装饰为 validated_field
(即带自定义验证器的数据类字段)。
validated_field
创建带有自定义验证的数据类字段。
huggingface_hub.dataclasses.validated_field
< 源 >( validator: typing.Union[typing.List[typing.Callable[[typing.Any], NoneType]], typing.Callable[[typing.Any], NoneType]] default: typing.Union[typing.Any, dataclasses._MISSING_TYPE] = <dataclasses._MISSING_TYPE object at 0x7fd63e62b910> default_factory: typing.Union[typing.Callable[[], typing.Any], dataclasses._MISSING_TYPE] = <dataclasses._MISSING_TYPE object at 0x7fd63e62b910> init: bool = True repr: bool = True hash: typing.Optional[bool] = None compare: bool = True metadata: typing.Optional[typing.Dict] = None **kwargs: typing.Any )
创建带有自定义验证器的数据类字段。
对于对字段应用多个检查很有用。如果只应用一个规则,请查看 as_validated_field
装饰器。
错误
严格数据类的基本异常。
当严格数据类定义不正确时抛出的异常。
class huggingface_hub.errors.StrictDataclassFieldValidationError
< 源 >( field: str cause: Exception )
当严格数据类在给定字段的验证失败时抛出的异常。
为什么不使用 pydantic?(或 attrs?或 marshmallow_dataclass?)
- 请参阅 https://github.com/huggingface/transformers/issues/36329 中关于添加 Pydantic 作为依赖的讨论。这将是一个沉重的添加,需要仔细的逻辑来支持 v1 和 v2。
- 我们不需要 Pydantic 的大部分功能,特别是那些与自动类型转换、jsonschema、序列化、别名等相关的功能。
- 我们不需要从字典实例化类的能力。
- 我们不想修改数据。在
@strict
中,“验证”意味着“检查值是否有效”。在 Pydantic 中,“验证”意味着“类型转换值,可能修改它,然后检查它是否有效”。 - 我们不需要极速验证。
@strict
并非为性能至关重要的高负载而设计。常见用例涉及验证模型配置(执行一次,与运行模型相比可忽略不计)。这使我们能够保持代码最少。