Можно ли получить доступ к аргументам ключевого слова, переданным в поле в базовой модели Pydantic?

Мне нужно получить доступ к my_key в Pydantic Field, как показано ниже:


class MyModel(BaseModel):
    x: str = Field(default=None, my_key=7)

    def print_field_objects(self):
        for obj in self.something_something:  # What do I use here
            print(obj.my_key)                 # ... so that i can use my_key?

Я пытался посмотреть, что содержит self, например self.__dict__, но не смог найти. Можно ли вообще получить доступ my_key?

Мне это нужно для моей конечной точки FastAPI.

Мутабельность и переработка объектов в Python
Мутабельность и переработка объектов в Python
Объекты являются основной конструкцией любого языка ООП, и каждый язык определяет свой собственный синтаксис для их создания, обновления и...
Другой маршрут в Flask Python
Другой маршрут в Flask Python
Flask - это фреймворк, который поддерживает веб-приложения. В этой статье я покажу, как мы можем использовать @app .route в flask, чтобы иметь другую...
14 Задание: Типы данных и структуры данных Python для DevOps
14 Задание: Типы данных и структуры данных Python для DevOps
Проверить тип данных используемой переменной, мы можем просто написать: your_variable=100
Python PyPDF2 - запись метаданных PDF
Python PyPDF2 - запись метаданных PDF
Python скрипт, который будет записывать метаданные в PDF файл, для этого мы будем использовать PDF ридер из библиотеки PyPDF2 . PyPDF2 - это...
Переменные, типы данных и операторы в Python
Переменные, типы данных и операторы в Python
В Python переменные используются как место для хранения значений. Пример переменной формы:
Почему Python - идеальный выбор для проекта AI и ML
Почему Python - идеальный выбор для проекта AI и ML
Блог, которым поделился Harikrishna Kundariya в нашем сообществе Developer Nation Community.
0
0
98
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Поле не принимает произвольных аргументов, чего именно вы пытаетесь добиться, возможно есть более подходящее решение.

По вашему другому вопросу x — это атрибут класса, определение которого можно найти в self.__class__.__fields__, а его значение экземпляра можно найти, вызвав self.x

Мне нужно хранить больше информации в определении поля. Я делаю фильтры, похожие на django-rest-framework. Я храню их там просто для того, чтобы определить мои фильтры более понятным способом.

Riya 22.11.2022 06:42

Используя ваш ответ, мне удалось получить доступ к значению: self.__class__.__fields__['x'].field_info.extra['my_key'], спасибо! Это правильный способ сделать это?

Riya 22.11.2022 06:43

Там есть! CompanyFilter.schema()['MyModel']['x']['my_key']. Спасибо, вы направили меня в правильном направлении. Не могли бы вы адаптировать свой ответ, и я с радостью приму его.

Riya 22.11.2022 06:48
Ответ принят как подходящий

Вы можете сгенерировать представление схемы JSON модели , используя метод BaseModel .schema(), а затем положиться на эту функциональность настройки поля, которая:

** любые другие аргументы ключевого слова (например, examples) будут добавлены дословно в схему поля

Другими словами, любые другие произвольные аргументы ключевого слова, переданные в Field, которые не потребляются или не используются Pydantic (или каким-либо пользовательским созданием/экземпляром), будут присутствовать в представлении схемы JSON этого поля.

Итак, в этом случае ваш my_key должен присутствовать на схеме модели:

In [4]: class MyModel(BaseModel):
   ...:     x: str = Field(default=None, my_key=7)
   ...: 

In [5]: MyModel.schema()
Out[5]: 
{'title': 'MyModel',
 'type': 'object',
 'properties': {'x': {'title': 'X', 'my_key': 7, 'type': 'string'}}}
                                    ^^^^^^^^^^^^
                                    ||||||||||||

Затем у вас может быть метод экземпляра, который выглядит следующим образом:

In [21]: class MyModel(BaseModel):
    ...:     x: str = Field(default=None, my_key=7)
    ...:     y: int = Field(default=1, my_key=42)
    ...: 
    ...:     def print_field_objects(self):
    ...:         for field_name, field in self.schema()["properties"].items():
    ...:             print(field["my_key"])
    ...: 

In [22]: m1 = MyModel()

In [23]: m1.print_field_objects()
7
42

Но, поскольку схема модели и определения Field привязаны к классу, а не к экземпляру, несколько экземпляров будут иметь одинаковое значение:

In [28]: m1 = MyModel()

In [29]: m1.print_field_objects()
7
42

In [30]: m2 = MyModel()

In [31]: m2.print_field_objects()
7
42

Таким образом, было бы точнее сделать его методом класса, поскольку my_key все равно не изменится с разными значениями поля x или с разными экземплярами:

In [35]: class MyModel(BaseModel):
    ...:     x: str = Field(default=None, my_key=7)
    ...:     y: int = Field(default=1, my_key=42)
    ...: 
    ...:     @classmethod
    ...:     def print_field_objects(cls):
    ...:         for field_name, field in cls.schema()["properties"].items():
    ...:             print(field_name, field.get("my_key"))
    ...: 

In [36]: MyModel.print_field_objects()
x 7
y 42

Другие вопросы по теме