Мне нужно очистить значения по умолчанию в модели 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
Должно быть value: int = Field(default=1, validate_default=True)
Библиотека 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()
Что он делает:
все вышеперечисленное сделано без воссоздания экземпляра. Сейчас
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 Спасибо, что заметили мою ошибку. отступы действительно имеют решающее значение. спасибо за тройной совет, я не знал.
Я бы настоятельно рекомендовал сделать это как можно более явно. Ваши методы должны быть легко читаемыми и понятными с первого взгляда. Кроме того, подумайте о масштабируемости и потенциальных ошибках, например, при добавлении новых вложенных атрибутов или когда некоторые атрибуты не имеют значения по умолчанию.
Вы можете дополнительно перенести свои значения в константы, но идея следующая:
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()