如果我创建一个 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
而没有别名。这在语义上不太清晰。
您可以通过实现自己的
__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!