tg-me.com/BookPython/3619
Last Update:
default_factory
в dataclass
: мощнее, чем кажется
Многие используют dataclass
как удобный способ задать структуру с полями. Но редко кто по-настоящему раскрывает силу default_factory
. А зря — он спасает от багов и даёт гибкость.
Когда нужно задать значение по умолчанию для поля в dataclass
, логично тянуться к default=
. Но если это изменяемый тип (например, список или словарь) — вас поджидает ловушка.
from dataclasses import dataclass, field
@dataclass
class User:
name: str
tags: list[str] = [] # ⚠️ опасно!
Все экземпляры
User
будут делить один и тот же список. То есть:
a = User("Alice")
b = User("Bob")
a.tags.append("admin")
print(b.tags) # ['admin'] 😱
Вместо этого используйте
default_factory
:
@dataclass
class User:
name: str
tags: list[str] = field(default_factory=list)
Теперь у каждого
User
будет свой список:
a = User("Alice")
b = User("Bob")
a.tags.append("admin")
print(b.tags) # []
Но
default_factory
не только про списки. Это отличный способ задать любое значение "по умолчанию", включая кастомную логику:
import uuid
@dataclass
class Session:
id: str = field(default_factory=lambda: str(uuid.uuid4()))
Или, например, значения из окружения:
import os
@dataclass
class Config:
debug: bool = field(default_factory=lambda: os.getenv("DEBUG") == "1")
Кстати, это ещё и отличное место для внедрения DI:
@dataclass
class Service:
client: "Client" = field(default_factory=create_default_client)
default_factory
— это маленький хак, который позволяет сделать код чище и безопаснее, особенно когда работаешь с изменяемыми структурами или сложной инициализацией.👉@BookPython
BY Библиотека Python разработчика | Книги по питону
Warning: Undefined variable $i in /var/www/tg-me/post.php on line 283
Share with your friend now:
tg-me.com/BookPython/3619