You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 04:26:05