
pydantic 的 `basemodel` 会自动将带类型注解的字段(如 `test_value: str = “”`)注册为模型字段,并在类构建阶段移除其作为类属性的存在,因此 `class.test_value` 会触发 `attributeerror`;该值仅存在于实例中。
Pydantic 的设计目标是构建数据验证与序列化的运行时模型,而非普通类。当定义继承自 BaseModel 的类时,其元类(ModelMetaclass)会在类创建过程中扫描所有带类型注解的属性(即 field),并将它们转换为模型字段(ModelField),同时从类的 __dict__ 和 dir() 中移除——这意味着这些名称不再作为类属性存在,仅保留在实例层面。
✅ 正确访问方式:通过实例访问
from pydantic import BaseModel class TestClass(BaseModel): TEST_VALUE: str = "default" # ❌ 错误:类属性不存在 # print(TestClass.TEST_VALUE) # AttributeError! # ✅ 正确:实例属性可访问 instance = TestClass() print(instance.TEST_VALUE) # 输出: "default" # 也可在初始化时传入值 instance2 = TestClass(TEST_VALUE="custom") print(instance2.TEST_VALUE) # 输出: "custom"
✅ 若需真正的类属性(不参与验证/序列化),请避免类型注解或使用 ClassVar
from pydantic import BaseModel from typing import ClassVar class TestClass(BaseModel): # 实例字段(受 Pydantic 管理) name: str = "anonymous" # 真正的类属性:不参与验证、不序列化、不被 BaseModel 处理 VERSION: ClassVar[str] = "1.0.0" CONFIG_PATH: ClassVar[str] = "/etc/app.yaml" print(TestClass.VERSION) # ✅ 正常输出 "1.0.0" print(TestClass().VERSION) # ✅ 实例也可访问(因 ClassVar 是类共享的) print(TestClass().name) # ✅ 实例字段正常工作 # print(TestClass().CONFIG_PATH) # ✅ 同样可用
⚠️ 注意:ClassVar 是唯一被 Pydantic 明确认可的“跳过字段处理”的方式。直接使用 TEST_VALUE = “xxx”(无类型注解)虽在某些版本中看似有效,但属于未定义行为,不推荐——它可能被忽略、覆盖或引发兼容性问题。
? 验证机制说明
你可以用 dir() 或 vars() 辅助判断:
print('TEST_VALUE' in dir(TestClass)) # False print('TEST_VALUE' in dir(TestClass())) # True print('VERSION' in dir(TestClass)) # True(ClassVar 保留为类属性)
总之:Pydantic 中的字段 ≠ python 类属性。如需配置常量、版本号、默认路径等静态元信息,请始终使用 typing.ClassVar;如需数据建模字段,则接受其“仅实例可用”的约定,并通过 model_dump()、model_fields 等 API 进行元数据操作。