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支援的型別包括:
- Any
- Union
- 可選
- Literal
- 列表
- 字典
- 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 )
裝飾器,用於為資料類新增嚴格驗證。
此裝飾器必須放在 @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 -1validate_typed_dict
方法,用於驗證字典是否符合 TypedDict 類中定義的型別。
這相當於資料類的驗證,但用於 TypedDict。由於型別字典永遠不會例項化(僅由靜態型別檢查器使用),因此必須手動呼叫驗證步驟。
huggingface_hub.dataclasses.validate_typed_dict
< 原始碼 >( schema: type data: dict )
驗證字典是否符合 TypedDict 類中定義的型別。
在後臺,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 -1as_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
< source >( validator: typing.Union[list[typing.Callable[[typing.Any], NoneType]], typing.Callable[[typing.Any], NoneType]] default: typing.Union[typing.Any, dataclasses._MISSING_TYPE] = <dataclasses._MISSING_TYPE object at 0x7ff1eeb7d510> default_factory: typing.Union[typing.Callable[[], typing.Any], dataclasses._MISSING_TYPE] = <dataclasses._MISSING_TYPE object at 0x7ff1eeb7d510> init: bool = True repr: bool = True hash: typing.Optional[bool] = None compare: bool = True metadata: typing.Optional[dict] = None **kwargs: typing.Any )
建立一個帶有自定義驗證器的 dataclass 欄位。
這對於對欄位應用多個檢查很有用。如果只應用一個規則,請檢視 as_validated_field 裝飾器。
錯誤
嚴格 dataclass 的基類異常。
當嚴格 dataclass 定義不當時丟擲的異常。
class huggingface_hub.errors.StrictDataclassFieldValidationError
< source >( field: str cause: Exception )
當嚴格 dataclass 的給定欄位驗證失敗時丟擲的異常。
為什麼不使用 Pydantic?(或 attrs?或 marshmallow_dataclass?)
- 有關將 Pydantic 新增為依賴項的討論,請參閱 https://github.com/huggingface/transformers/issues/36329。這將是一個很大的改動,並且需要仔細的邏輯來同時支援 v1 和 v2。
- 我們不需要 Pydantic 的大部分功能,特別是那些與自動轉換、jsonschema、序列化、別名等相關的。
- 我們不需要從字典例項化類的能力。
- 我們不希望修改資料。在
@strict中,“驗證”意味著“檢查值是否有效”。在 Pydantic 中,“驗證”意味著“轉換值,可能修改它,然後檢查它是否有效”。 - 我們不需要極快的驗證。
@strict不是為效能至關重要的重負載設計的。常見用例包括驗證模型配置(僅執行一次,與執行模型相比可以忽略不計)。這使我們能夠保持程式碼的簡潔。