Atualizado: 04/11/2024

Módulo Dataclasses - Python

O módulo dataclasses fornece o decorador dataclass, que permite criar data classes, as quais reduzem significativamente o código repetitivo (boilerplate) das classes. Geralmente, tais classes são destinadas a armazenar algum estado ou dados, quando não é necessário algum comportamento na forma de funções.

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, na qual, na função construtora __init__, são estabelecidos dois atributos: name e age. Em seguida, criamos um objeto dessa classe e exibimos os valores de seus atributos no console.

Agora, vamos modificar este programa, transformando a classe Person em uma data class:

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 o decorador dataclass e o aplicamos à classe Person. Nesse caso, não precisamos mais especificar o construtor, a função __init__. Simplesmente declaramos os atributos, e o Python irá gerar o construtor, no qual podemos passar os valores para os atributos do objeto.

Assim, reduzimos a definição da classe e a tornamos mais simples. Mas a funcionalidade do decorador dataclass não se limita à criação do método __init__. Na realidade, a data class

@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__, também são definidas as funções __repr__() para retornar uma representação em string e __eq__() para comparar dois objetos. Para entender melhor como funciona a sobrecarga de operadores em Python, consulte este artigo. Aplicação dessas funções: Aplicação dessas funções:

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 permite gerar código adicional e personalizar a funcionalidade da data class:

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:

  • init: se for True, gera a função __init__(). Por padrão, é True.

  • repr: se for True, gera a função __repr__(), que retorna uma representação em string do objeto. Por padrão, é True.

  • eq: se for True, gera a função __eq__(), que compara dois objetos. Por padrão, é True.

  • order: se for True, gera as funções __lt__ (operação <), __le__ (<=), __gt__ (>), __ge__ (>=), que são usadas para ordenar objetos. Por padrão, é False.

  • unsafe_hash: se for True, gera a função __hash__(), que retorna o hash do objeto. Por padrão, é 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__ para criar uma representação em string do objeto.

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
Política de Privacidade

Copyright © www.programicio.com Todos os direitos reservados

É proibida a reprodução do conteúdo desta página sem autorização prévia do autor.

Contato: programicio@gmail.com