如何让Pydantic类的类字段不可变?
实现带不可变类字段的Pydantic类
Pydantic的allow_mutation=False配置仅对实例字段生效,无法限制类级别的字段(以_开头的类变量)被修改。要实现类字段的不可变,可通过以下两种方式实现:
方法一:自定义元类拦截类属性修改
通过继承Pydantic模型的元类,重写__setattr__方法来禁止修改指定的类字段:
from pydantic import BaseModel class ImmutableClassFieldsMeta(type(BaseModel)): def __setattr__(cls, name, value): # 定义需要保护的类字段列表 protected_fields = ('_name', '_age') # 若字段已存在且在保护列表中,抛出错误阻止修改 if name in protected_fields and hasattr(cls, name): raise TypeError(f"无法修改不可变类字段 '{name}'") super().__setattr__(name, value) class ImmutableModel(BaseModel, metaclass=ImmutableClassFieldsMeta): _name: str = "My Name" _age: int = 25 # 尝试修改受保护字段会触发错误 try: ImmutableModel._age = 26 except TypeError as e: print(e) # 输出:无法修改不可变类字段 '_age' print("Class variables:") print(f"Name: {ImmutableModel._name}") print(f"Age: {ImmutableModel._age}")
方法二:重写类的__setattr__类方法
直接在Pydantic模型中定义类级别的__setattr__方法,拦截类属性的赋值操作:
from pydantic import BaseModel class ImmutableModel(BaseModel): _name: str = "My Name" _age: int = 25 @classmethod def __setattr__(cls, name, value): protected_fields = ('_name', '_age') if name in protected_fields and hasattr(cls, name): raise TypeError(f"类字段 '{name}' 为不可变") super().__setattr__(name, value) # 尝试修改受保护字段会触发错误 try: ImmutableModel._age = 26 except TypeError as e: print(e) print("Class variables:") print(f"Name: {ImmutableModel._name}") print(f"Age: {ImmutableModel._age}")
额外说明
- 若需要禁止新增类字段,可移除判断逻辑中的
and hasattr(cls, name),这样任何对类字段的赋值(包括新增)都会被拦截。 - 以上代码完全兼容Python 3.6.13和pydantic==1.9.2版本。
内容的提问来源于stack exchange,提问作者Arud Seka Berne S
相关产品推荐
相关产品推荐

