获取pydantic类的所有字段名的快捷方式



类的最小示例:

from pydantic import BaseModel
class AdaptedModel(BaseModel):
def get_all_fields(self, alias=False):
return list(self.schema(by_alias=alias).get("properties").keys())
class TestClass(AdaptedModel):
test: str

它的工作方式:

dm.TestClass.get_all_fields(dm.TestClass)

有没有办法让它在不上课的情况下发挥作用?

想要获得所有字段名称的方法:

dm.TestClass.get_all_fields()

如果将字段名称指定给某个属性,也会起作用。只要用任何方法让它更可读

只使用__fields__:怎么样

from pydantic import BaseModel
class AdaptedModel(BaseModel):
parent_attr: str
class TestClass(AdaptedModel):
child_attr: str

TestClass.__fields__

输出:

{'parent_attr': ModelField(name='parent_attr', type=str, required=True),
'child_attr': ModelField(name='child_attr', type=str, required=True)}

这只是一个dict,您只需通过以下方式即可获得字段名称:TestClass.__fields__.keys()

请参见模型属性:https://pydantic-docs.helpmanual.io/usage/models/#model-属性

好的,解决方案是使用类方法而不是实例方法:

from pydantic import BaseModel, Field
class AdaptedModel(BaseModel):
@classmethod
def get_field_names(cls,alias=False):
return list(cls.schema(alias).get("properties").keys())
class TestClass(AdaptedModel):
test: str = Field(alias="TEST")

我们使用的是Python 3.6.8,显然它已经介绍过了。为了完整起见,有人能评论一下@classmethod的存在吗?我认为从3.6开始。

这里有一个解决方案,它结合了miksus5th的答案,支持按别名列出字段名:

from pydantic import BaseModel
from pydantic.fields import ModelField, Field
class AdaptedModel(BaseModel):
base_field_1: str = Field(alias="base_field_1_alias")
@classmethod
def get_field_names(cls, by_alias=False) -> list[str]:
field_names = []
for k, v in cls.__fields__.items():
if by_alias and isinstance(v, ModelField):
field_names.append(v.alias)
else:
field_names.append(k)
return field_names
class TestClass(AdaptedModel):
test_field_1: str = Field(alias="test_field_1_alias")
test_field_2: str

以以下方式使用:

print(TestClass.get_field_names(by_alias=True))

输出

['base_field_1_alias', 'test_field_1_alias', 'test_field_2']

或者,您可以使用by_alias=False(默认值(获得非别名列表:

print(TestClass.get_field_names(by_alias=False))

输出:

['base_field_1', 'test_field_1', 'test_field_2']

如果您还需要每个字段的类型,您可以使用jsonref:

import jsonref
from pprint import pprint
from enum import Enum
class Values(Enum):
a = 'a'
b = 'b'

class Mdl(BaseModel):
par: Values = Field(
title="par",
description="description of my parameter"
)
par2: str = Field(
title="par2",
description="description of my parameter"
)
par3: int = Field(
title="par3",
description="description of my parameter"
)
class Config:
""" Automatically convert enum to values """
use_enum_values = True

pprint(jsonref.loads(Mdl.schema_json()))

产生

{'definitions': {'Values': {'description': 'An enumeration.',
'enum': ['a', 'b'],
'title': 'Values'}},
'properties': {'par': {'allOf': [{'title': 'Values', 'description': 'An enumeration.', 'enum': ['a', 'b']}],
'description': 'description of my parameter',
'title': 'MyParameter'},
'par2': {'description': 'description of my parameter',
'title': 'MyParameter',
'type': 'string'},
'par3': {'description': 'description of my parameter',
'title': 'MyParameter',
'type': 'integer'}},
'required': ['par', 'par2', 'par3'],
'title': 'Mdl',
'type': 'object'}

后者可能会用进一步清洗

sch = jsonref.loads(Mdl.schema_json())
for par in sch['properties']:
if 'allOf' in sch['properties']['par']:
if 'enum' in sch['properties']['par']['allOf'][0]:
sch['properties']['par']['title'] = sch['properties']['par']['allOf'][0]['title']
sch['properties']['par']['allowed_values'] = sch['properties']['par']['allOf'][0]['enum']
sch['properties']['par'].pop('allOf')

返回

{'definitions': {'Values': {'description': 'An enumeration.',
'enum': ['a', 'b'],
'title': 'Values'}},
'properties': {'par': {'allowed_values': ['a', 'b'],
'description': 'description of my parameter',
'title': 'Values'},
'par2': {'description': 'description of my parameter',
'title': 'MyParameter',
'type': 'string'},
'par3': {'description': 'description of my parameter',
'minimum': 0,
'title': 'MyParameter',
'type': 'integer'}},
'required': ['par', 'par2', 'par3'],
'title': 'Mdl',
'type': 'object'}

最新更新