tgoop.com/hw_code/597
Last Update:
Дрочим датаклассы v 2.0 💅💅
Приветствую, дорогие читатели! Ваш любимый шизоид снова выходит на связь. В этом посте мы закончим разбирать датаклассы (надеюсь). В прошлом посте я не осветил такой интересный вопрос, как "зачем же все-таки они нужны?". Поясняю: вам необходимо создавать датаклассы в первую очередь для хранения и управления данными (как и следует из их названия). Либо, если вы хотите упростить себе задачу и писать меньше кода, воспользовавшись автоматической генерацией некоторых методов: __init__
, __repr__
, etc.
У нас в проектах это много где используется, в основном для упрощения управления и хранения различного рода данных.
Исключение аргументов из __init__
Рассмотрим пример, когда нам нужно убрать аргумент из инициализатора, например user_id
, который нам должен генерироваться автоматически. Для этого в аргумент добавим init=False
.
import random
def my_super_ultra_id_func() -> int:
return random.randint(0, 1000)
@dataclass
class User:
user_id: int = field(init=False, default_factory=my_super_ultra_id_func)
name: str = field(default="")
is_active: bool = True
email_addresses: list[str] = field(default_factory=list)
Используем
__post_init__
для создания полейИногда нам необходимо например добавить переменную, которая будет являться комбинацией других. Для этого воспользуемся методом
__post_init__
.
@dataclass
class User:
user_id: int = field(default_factory=my_super_ultra_id_func)
name: str = field(default="")
is_active: bool = True
email_addresses: list[str] = field(default_factory=list, repr=False)
search_string: str = field(init=False)
def __post_init__(self) -> None:
self.search_string = f"{self.user_id}: {self.name}"
user = User(user_id=1, name="hw_code", is_active=False, email_addresses=["[email protected]"])
Выведет:
User(user_id=1, name='hw_code', is_active=False, search_string='1: hw_code')
Private/protected
Абсолютно аналогично созданию private/protected переменной в обычном классе. Просто добавляем _ перед именем.
_search_string: str = field(init=False)
Read only поля датакласса
Допустим мы хотим сделать так, чтобы после инициализации значения полей нельзя было поменять. По умолчанию, когда мы используем декоратор
@dataclass
, значение аргумента frozen
в нем равно False
. Чтобы сделать "заморозить" поля датакласса, меняем это значение на True
.
@dataclass(frozen=True)
class User:
user_id: int = field(default_factory=my_super_ultra_id_func)
name: str = field(default="")
is_active: bool = True
email_addresses: list[str] = field(default_factory=list, repr=False)
search_string: str = field(init=False)
def __post_init__(self) -> None:
self.search_string = f"{self.user_id}: {self.name}"
Теперь после инициализации мы не сможем изменить значения полей:
user = User(user_id=1, name="hw_code", is_active=False, email_addresses=["[email protected]"])
user.name = "Big Dick" # ошибка
kw_only
аргументУказывая этот аргумент мы можем вынудить программиста, использующего наш датакласс, использовать только именованые аргументы при инициализации.
@dataclass(kw_only=True)
class User:
user_id: int = field(default_factory=my_super_ultra_id_func)
name: str = field(default="")
is_active: bool = True
email_addresses: list[str] = field(default_factory=list, repr=False)
search_string: str = field(init=False)
def __post_init__(self) -> None:
self.search_string = f"{self.user_id}: {self.name}"
# сработает
user = User(user_id=1, name="hw_code", is_active=False, email_addresses=["[email protected]"])
# не сработает
user = User(1, "hw_code", False, ["[email protected]"])
Ну че, все готовы к началу рабочей недели? 🗿🗿🗿
@hw_code
BY Hello World
Share with your friend now:
tgoop.com/hw_code/597