Hub Python 函式庫文件

嚴謹資料類別

Hugging Face's logo
加入 Hugging Face 社群

並獲得增強的文件體驗

開始使用

嚴謹資料類別

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

支援的型別包括:

  • Any
  • Union
  • 可選配置
  • Literal
  • List
  • Dict
  • Tuple
  • Set

以及這些型別的任何組合。如果您需要更複雜的型別驗證,可以透過自訂驗證器來實現。

類別驗證器

命名為 `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 )

參數

  • cls — 要轉換為嚴謹資料類別的類別。
  • accept_kwargs (bool, 選填) — 如果為 True,允許在 `__init__` 中使用任意關鍵字引數。預設為 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

validate_typed_dict

用於驗證字典是否符合 `TypedDict` 類別中定義的型別的方法。

這相當於資料類別驗證,但適用於 `TypedDict`。由於型別字典從不被實例化(僅由靜態型別檢查器使用),因此必須手動呼叫驗證步驟。

huggingface_hub.dataclasses.validate_typed_dict

< >

( schema: type data: dict )

參數

  • schema (type[TypedDictType]) — 定義預期結構和型別的 TypedDict 類別。
  • data (dict) — 要驗證的字典。

引發

StrictDataclassFieldValidationError

  • StrictDataclassFieldValidationError — 如果字典中的任何欄位不符合預期型別。

驗證字典是否符合 TypedDict 類別中定義的型別。

在內部,型別字典會轉換為嚴謹資料類別,並使用 `@strict` 裝飾器進行驗證。

範例

>>> from typing import Annotated, TypedDict
>>> from huggingface_hub.dataclasses import validate_typed_dict

>>> def positive_int(value: int):
...     if not value >= 0:
...         raise ValueError(f"Value must be positive, got {value}")

>>> class User(TypedDict):
...     name: str
...     age: Annotated[int, positive_int]

>>> # Valid data
>>> validate_typed_dict(User, {"name": "John", "age": 30})

>>> # Invalid type for age
>>> validate_typed_dict(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 for age
>>> validate_typed_dict(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: Callable )

參數

  • validator (Callable) — 一個接受值作為輸入,並在值無效時引發 ValueError/TypeError 的方法。

將驗證器函式裝飾為 `validated_field`(即帶有自訂驗證器的資料類別欄位)。

validated_field

建立帶有自訂驗證的資料類別欄位。

huggingface_hub.dataclasses.validated_field

< >

( validator: list[collections.abc.Callable[[typing.Any], None]] | collections.abc.Callable[[typing.Any], None] default: typing.Union[typing.Any, dataclasses._MISSING_TYPE] = <dataclasses._MISSING_TYPE object at 0x7f3f19e99ff0> default_factory: collections.abc.Callable[[], typing.Any] | dataclasses._MISSING_TYPE = <dataclasses._MISSING_TYPE object at 0x7f3f19e99ff0> init: bool = True repr: bool = True hash: bool | None = None compare: bool = True metadata: dict | None = None **kwargs: typing.Any )

參數

  • validator (Callablelist[Callable]) — 一個接受值作為輸入,並在值無效時引發 ValueError/TypeError 的方法。可以是驗證器列表以應用多個檢查。
  • **kwargs — 要傳遞給 dataclasses.field() 的額外引數。

建立帶有自訂驗證器的資料類別欄位。

可用於對欄位應用多個檢查。如果只應用一個規則,請查看 `as_validated_field` 裝飾器。

錯誤

class huggingface_hub.errors.StrictDataclassError

< >

( )

嚴謹資料類別的基礎例外。

class huggingface_hub.errors.StrictDataclassDefinitionError

< >

( )

當嚴謹資料類別定義不正確時引發的例外。

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` 並非為效能至關重要的繁重負載而設計。常見的使用情境涉及驗證模型配置(執行一次,與執行模型相比可忽略不計)。這使我們能夠保持程式碼的最小化。
在 GitHub 上更新

© . This site is unofficial and not affiliated with Hugging Face, Inc.