Кратко
Секция статьи "Кратко"Описанный в PEP557 и добавленный в версий 3.7 модуль dataclasses, упрощают создание классов, в которых в последующем хранятся некие данные. С помощью декоратора @dataclass, у нас автоматически генерируются магические методы
и
.
Практика
Секция статьи "Практика"Допустим мы хотим создать класс Person, для этого нам понадобится написать следующий код:
class Person: def __init__(self, full_name, age = 1): self.full_name = full_name self.age = age def __repr__(self): return f"{self.__class__.__name__}(full_name='{self.full_name}', age={self.age})"
class Person: def __init__(self, full_name, age = 1): self.full_name = full_name self.age = age def __repr__(self): return f"{self.__class__.__name__}(full_name='{self.full_name}', age={self.age})"
В случае с dataclasses, мы можем написать (очень важна аннотация типов, т.к. атрибуты без аннотаций будут проигнорированы и приведет к исключению NameError):
from dataclasses import dataclass@dataclassclass Person: full_name: str age: int = 1
from dataclasses import dataclass @dataclass class Person: full_name: str age: int = 1
А магические методы
и
как и было сказано ранее, сгенерируются автоматически. Обратите внимание, мы также можем задавать значения по умолчанию для атрибутов. Однако мы можем еще упростить этот код:
from dataclasses import make_dataclassPerson = make_dataclass("Person", ["full_name", "age"])
from dataclasses import make_dataclass Person = make_dataclass("Person", ["full_name", "age"])
Из полезного в модуле есть дополнительно методы, которые позволяют вернуть атрибуты класса в виде кортежа или словаря.
from dataclasses import asdict, astupleprint(asdict(Person("John Doe", 20))))# {'full_name': 'John Doe', 'age': 20}
from dataclasses import asdict, astuple print(asdict(Person("John Doe", 20)))) # {'full_name': 'John Doe', 'age': 20}
С помощью параметра frozen можно закрыть изменение экземпляров dataclass-а:
from dataclasses import dataclass@dataclass(frozen=True)class Person: full_name: str age: int = 1person = Person("John Doe", 20)person.email = "Doe@gmail.com"# raise dataclasses.FrozenInstanceError: cannot assign to field 'email'
from dataclasses import dataclass @dataclass(frozen=True) class Person: full_name: str age: int = 1 person = Person("John Doe", 20) person.email = "Doe@gmail.com" # raise dataclasses.FrozenInstanceError: cannot assign to field 'email'
Напоследок, dataclasses - исходя из названия классы, которые можно наследовать и производить любые действия, как и с обычными классами в питоне. Ссылка для лучшего ознакомления: