Как очистить объект pydantic до значений по умолчанию?

Мне нужно очистить значения по умолчанию в модели Pydantic. Я не могу воссоздать объект, поскольку в моем случае на него есть ссылки, которые необходимо сохранить. Не могли бы вы показать мне лучшие практики для этого?

Мне нужно что-то вроде этого примера.

from pydantic import BaseModel, Field


class MyObject(BaseModel):
    value: int = Field(default=1)


my_object = MyObject(value1=2)

# Reference to object, that need to be preserved
reference = [my_object]

# How to clear object to default values?
my_object.clear()
assert reference[0].value == 1
github.com/pydantic/pydantic/discussions/3139
sahasrara62 16.07.2024 09:29

Должно быть value: int = Field(default=1, validate_default=True)

toyota Supra 16.07.2024 10:21
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
2
72
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Библиотека pydantic предоставляет именно те инструменты, которые позволяют сделать это с помощью класса BaseModel.

Что вам нужно сделать, так это определить свой ясный метод для вашего класса:

from pydantic import BaseModel, Field

    def foo():
        return 2


    class MyObject(BaseModel):
        value1: int = Field(default=1)
        value2: Any = Field(default=foo())
        ...

        def clear(self):
            for field, field_info in self.model_fields.items():
                if field_info.default_factory:
                    default_value = field_info.default_factory()
                else:
                    default_value = field_info.default
                setattr(self, field, default_value)
            self.model_fields_set.clear()

Что он делает:

  • перебрать все поля, установленные в вашей базовой модели. (содержится в словаре model_fields).
  • проверьте (с помощью оператора if/else) природу данного поля (было ли его значение по умолчанию установлено константой, как в вашем примере, или вызываемым объектом, здесь с помощью функции foo)
  • получить значение по умолчанию
  • сбросить его

все вышеперечисленное сделано без воссоздания экземпляра. Сейчас

my_object = MyObject(value1=2)

# Reference to object, that need to be preserved
reference = [my_object]

# How to clear object to default values?
my_object.clear()
assert reference[0].value == 1

Не должно вызывать никаких ошибок! Не стесняйтесь задавать любые вопросы

пожалуйста, исправьте отступы в фрагментах кода. Отступы — это не «красивая вещь» в Python — это фундаментальная часть синтаксиса: ваш код сводится к SyntaxError. Обратите внимание, что вы можете использовать тройные обратные галочки в качестве кавычек для кода вместо того, чтобы добавлять четыре пробела перед каждой строкой кода для форматирования.

jsbueno 16.07.2024 15:01

@jsbueno Спасибо, что заметили мою ошибку. отступы действительно имеют решающее значение. спасибо за тройной совет, я не знал.

Lrx 16.07.2024 15:11

Я бы настоятельно рекомендовал сделать это как можно более явно. Ваши методы должны быть легко читаемыми и понятными с первого взгляда. Кроме того, подумайте о масштабируемости и потенциальных ошибках, например, при добавлении новых вложенных атрибутов или когда некоторые атрибуты не имеют значения по умолчанию.

Вы можете дополнительно перенести свои значения в константы, но идея следующая:

class Bar(BaseModel):
    value: int | None = Field(default=None)

    def clear(self) -> None:
        """Revert all Bar values back to the default ones."""

        self.value = None

class Foo(BaseModel):
    value: int = Field(default=1)
    bar: Bar


    def clear(self):
        """Revert all Foo values back to the default ones."""

        self.value = 1
        self.bar.clear()


foo = Foo()
foo.clear()

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