如何在Pydantic中使用一个类的属性作为另一个类的类型?
Great question! When you need to reuse a specific field's type (and optionally its default value) from another Pydantic model, there are a few clean, maintainable ways to do this without duplicating code. Here are the most common approaches for your example:
1. Access the Class Annotations Directly
Python classes store their type hints in the __annotations__ dictionary, which you can access directly to pull the type from model A:
from pydantic import BaseModel from typing import Optional class A(BaseModel): a: int b: Optional[str] c: bool = False class B(BaseModel): a: str b: Optional[str] c: A.__annotations__['c'] = A.c # Reuses type AND default value from A's 'c'
This works because A.__annotations__['c'] gives you the exact type hint defined for c in class A. We also set the default to A.c to match the original default value if you want consistency across models.
2. Use Pydantic's Field Metadata
Pydantic models keep detailed information about each field in the __fields__ attribute. This is especially useful if the type was inferred by Pydantic or includes validation logic:
class B(BaseModel): a: str b: Optional[str] c: A.__fields__['c'].type_ = A.__fields__['c'].default
Here, A.__fields__['c'].type_ returns the resolved type of the field, and default pulls the original default value. This method is more Pydantic-native and handles edge cases like custom types or validators better.
3. Resolve Type Hints with typing.get_type_hints
If your model uses forward references (string-based type hints), typing.get_type_hints will resolve them correctly, making this a safe, robust option:
from typing import Optional, get_type_hints from pydantic import BaseModel class A(BaseModel): a: int b: Optional[str] c: bool = False class B(BaseModel): a: str b: Optional[str] c: get_type_hints(A)['c'] = A.c
get_type_hints returns a dictionary of fully resolved type hints for the class, so you don't have to worry about unresolved references.
Bonus: Reusing Multiple Fields
If you ever need to reuse multiple fields instead of just one, consider creating a mixin class or composing models. For example:
class CMixin(BaseModel): c: bool = False class A(CMixin, BaseModel): a: int b: Optional[str] class B(CMixin, BaseModel): a: str b: Optional[str]
This way, any changes to the c field in the mixin will automatically apply to both A and B.
内容的提问来源于stack exchange,提问作者shantanu rahut

