Módulo Dataclasses - Python
O módulo dataclasses
dataclass
Vamos considerar um exemplo simples:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
tom = Person("Tom", 38)
print(f"Name: {tom.name} Age: {tom.age}") # Name: Tom Age: 38
Aqui, definimos a classe Person
__init__
name
age
Agora, vamos modificar este programa, transformando a classe Person
from dataclasses import dataclass
@dataclass
class Person:
name: str
age: int
tom = Person("Tom", 38)
print(f"Name: {tom.name} Age: {tom.age}") # Name: Tom Age: 38
Para criar uma data class, importamos do módulo dataclasses
dataclass
Person
__init__
Assim, reduzimos a definição da classe e a tornamos mais simples. Mas a funcionalidade do decorador dataclass
__init__
@dataclass
class Person:
name: str
age: int
é equivalente ao seguinte:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __repr__(self):
return f"Person(name={self.name!r}, age={self.age!r})"
def __eq__(self, other):
if other.__class__ is self.__class__:
return (self.name, self.age) == (other.name, other.age)
return NotImplemented
Nesse caso, vemos que, além da função __init__
__repr__()
__eq__()
from dataclasses import dataclass
@dataclass
class Person:
name: str
age: int
tom = Person("Tom", 38)
bob = Person("Bob", 42)
tomas = Person("Tom", 38)
print(tom == tomas) # True
print(tom == bob) # False
print(tom) # Person(name='Tom', age=38)
Parâmetros do decorador dataclass
Com a ajuda de parâmetros, o decorador dataclass
def dataclass(cls=None, /, *, init=True, repr=True, eq=True, order=False,
unsafe_hash=False, frozen=False, match_args=True,
kw_only=False, slots=False)
Vamos considerar os parâmetros básicos:
: se forinit
, gera a funçãoTrue
. Por padrão, é__init__()
.True
: se forrepr
, gera a funçãoTrue
, que retorna uma representação em string do objeto. Por padrão, é__repr__()
.True
: se foreq
, gera a funçãoTrue
, que compara dois objetos. Por padrão, é__eq__()
.True
: se fororder
, gera as funçõesTrue
(operação <),__lt__
(<=),__le__
(>),__gt__
(>=), que são usadas para ordenar objetos. Por padrão, é__ge__
.False
: se forunsafe_hash
, gera a funçãoTrue
, que retorna o hash do objeto. Por padrão, é__hash__()
.False
Além disso, as funções que são criadas por padrão podem ser sobrescritas.
Aplicação dos parâmetros:
from dataclasses import dataclass
@dataclass(unsafe_hash=True, order=True)
class Person:
name: str
age: int
def __repr__(self):
return f"Person. Name: {self.name} Age: {self.age}"
tom = Person("Tom", 38)
print(hash(tom)) # Exemplo de saída: -421667297069596717
print(tom) # Person. Name: Tom Age: 38
Neste caso, ativamos a criação do hash e das funções de ordenação, além de sobrescrever explicitamente a função __repr__
Valores padrão
Se necessário, os atributos podem receber valores padrão caso não sejam passados valores a eles no construtor:
from dataclasses import dataclass
@dataclass
class Person:
name: str
age: int = 18
tom = Person("Tom", 38)
print(tom) # Person(name='Tom', age=38)
bob = Person("Bob")
print(bob) # Person(name='Bob', age=18)
Adicionando funcionalidade extra
Embora as data classes sejam destinadas principalmente ao armazenamento de dados, também é possível definir métodos adicionais:
from dataclasses import dataclass
@dataclass
class Person:
name: str
age: int
def say_hello(self):
print(f"{self.name} says hello")
tom = Person("Tom", 38)
tom.say_hello() # Tom says hello