Pydantic 可互换使用字段的别名和初始名称

问题描述 投票:0回答:1

如果我创建一个 Pydantic 模型,其中的字段具有别名,我希望能够互换使用初始名称或别名。创建对象时这是可能的(感谢

populate_by_name=True
),但使用对象时则不然。

from pydantic import BaseModel, ConfigDict, Field


class Resource(BaseModel):
    name: str = Field(alias="identifier")
    model_config = ConfigDict(populate_by_name=True)


r1 = Resource(name="a name")  # works
r2 = Resource(identifier="a name")  # works thanks to populate_by_name=True

print(r1.name)  # works
print(r2.identifier)  # AttributeError: 'Resource' object has no attribute 'identifier'

这是否可能,如果可能,如何实现?

另一种选择是使用

@computed_field
(
identifier
),它只返回属性
name
而没有别名。这在语义上不太清晰。

python-3.x pydantic pydantic-v2
1个回答
0
投票

您可以通过实现自己的

__getattr__
来通过别名动态查找模型字段来实现此行为。 :)

from pydantic import BaseModel, ConfigDict, Field


class Resource(BaseModel):
    model_config = ConfigDict(populate_by_name=True)

    name: str = Field(alias="identifier")

    def __getattr__(self, item):
        for field, meta in self.model_fields.items():
            if meta.alias == item:
                return getattr(self, field)
        return super().__getattr__(item)


r1 = Resource(name="a name")  # works
r2 = Resource(identifier="a name")  # works thanks to populate_by_name=True

print(r1.name)  # works
print(r2.identifier)  # dynamic lookup for `name`
print(r2.meep)  # AttributeError: 'Resource' object has no attribute 'meep'

不过,不要指望您的 IDE/编辑器提供任何 IDE IntelliSense!

© www.soinside.com 2019 - 2024. All rights reserved.