Pilhas nomeadas em Python: Como usar namedtuple facilmente?
Escrevendo um Código Pythonic e Limpo com namedtuple
O módulo collections
do Python fornece uma função de fábrica chamada namedtuple()
, que é especialmente projetada para tornar seu código mais Pythonic, quando você está trabalhando com tuplas. Com namedtuple()
, você pode criar tipos de sequência imutável que permitem acessar seus valores usando nomes descritivos de campo e a notação de ponto em vez de índices inteiros incertos.
Se você tem alguma experiência usando Python, então você sabe que escrever um código Pythonic é uma habilidade fundamental para os desenvolvedores Python. Neste tutorial, você vai aprimorar essa habilidade usando namedtuple
.
Neste tutorial, você aprenderá a:
- Criar classes
namedtuple
usandonamedtuple()
- Identificar e aproveitar os recursos incríveis do
namedtuple
- Usar instâncias de
namedtuple
para escrever um código Pythonic - Decidir se o uso de uma
namedtuple
é apropriado ou se deve-se usar uma estrutura de dados similar - Subclassificar uma
namedtuple
para fornecer novos recursos
Se você não possui todo o conhecimento necessário antes de começar este tutorial, não se preocupe! Você pode parar e revisar os recursos mencionados acima, conforme necessário.
Usando namedtuple para Escrever um Código Pythonic
Uma namedtuple
é uma fábrica de tipos de dados que cria subclasses de tuple
com campos nomeados. Ela é definida usando dois argumentos: um nome para a classe namedtuple
e uma string contendo os nomes dos campos.
Veja um exemplo abaixo:
Neste exemplo, criamos uma namedtuple
chamada Point
com os campos x
e y
. Em seguida, criamos uma instância dessa namedtuple
com os valores 1
e 2
. Em seguida, podemos acessar os campos da instância usando a notação de ponto.
Criando Classes Semelhantes a Tuplas com namedtuple()
A função namedtuple()
também aceita um argumento adicional opcional, que é uma string com os nomes dos campos separados por espaço, em vez de uma lista ou tupla.
Veja um exemplo abaixo:
Neste exemplo, criamos uma namedtuple
chamada Circle
usando uma string com os nomes dos campos separados por espaço. Podemos criar uma instância dessa namedtuple
da mesma forma que antes e acessar os campos usando a notação de ponto.
Explorando Recursos Adicionais das Classes namedtuple
As classes namedtuple
têm outros recursos interessantes além da capacidade de criar instâncias com campos nomeados. Vejamos alguns desses recursos.
Criando Instâncias de namedtuple a partir de Iteráveis
Você pode criar instâncias de namedtuple
usando iteráveis em vez de passar todos os valores como argumentos separados. Os elementos do iterável são atribuídos aos campos da namedtuple
na ordem em que são fornecidos.
Veja um exemplo abaixo:
Neste exemplo, criamos uma instância da namedtuple
Color
usando a função estática _make()
e passando uma lista com os valores dos campos. Os elementos da lista são atribuídos aos campos na ordem especificada.
Convertendo Instâncias de namedtuple em Dicionários
Você pode converter instâncias de namedtuple
em dicionários usando o método _asdict()
. Isso retorna um objeto OrderedDict
com os nomes dos campos como chaves e os respectivos valores das instâncias como valores.
Veja um exemplo abaixo:
Neste exemplo, criamos uma instância da namedtuple
Person
e depois a convertemos em um dicionário usando o método _asdict()
. O dicionário resultante p_dict
contém os nomes dos campos como chaves e os respectivos valores das instâncias como valores.
Substituindo Campos em Instâncias Existentes de namedtuple
Você pode substituir campos específicos em instâncias existentes de namedtuple
usando o método _replace()
. O método retorna uma nova instância da namedtuple
com os campos substituídos pelos novos valores especificados.
Veja um exemplo abaixo:
Neste exemplo, criamos uma instância da namedtuple
Person
chamada p
e depois a substituímos pelo campo age
usando o método _replace()
. O novo valor do campo é fornecido como argumento no formato campo=novo_valor
. A nova instância p_new
tem o campo age
substituído pelo novo valor fornecido.
Explorando Atributos Adicionais das namedtuple Classes
As classes namedtuple
também têm outros atributos adicionais úteis que podem ser acessados. Alguns desses atributos são:
._fields
: Retorna uma tupla com os nomes dos campos danamedtuple
.._make(iterable)
: Cria uma nova instância danamedtuple
usando o iterável fornecido.._asdict()
: Converte a instância danamedtuple
em um objetoOrderedDict
.._replace(**kwargs)
: Cria uma nova instância danamedtuple
, substituindo os campos fornecidos pelos novos valores.
Escrevendo um Código Pythonic com namedtuple
A principal vantagem de usar namedtuple
em vez de listas ou tuplas é a capacidade de acessar os valores pelos nomes dos campos, em vez de usar índices inteiros. Isso torna o código mais legível e menos propenso a erros.
Veja um exemplo abaixo:
Neste exemplo, criamos uma função get_books()
que retorna várias instâncias da namedtuple
Book
. Em seguida, chamamos essa função e atribuímos as instâncias retornadas a variáveis individuais. Por fim, usamos a notação de ponto para acessar os valores dos campos e imprimi-los.
Comparando namedtuple com Outras Estruturas de Dados
Durante o desenvolvimento de seu código, você pode se deparar com várias opções de estruturas de dados para armazenar e manipular seus dados. Aqui, vamos comparar o uso de namedtuple
com outras estruturas de dados comumente usadas no Python.
namedtuple vs Dicionário
Os dicionários são estruturas de dados muito flexíveis, pois permitem armazenar pares chave-valor de qualquer tipo, incluindo outros objetos. Eles são ideais quando você precisa associar um valor a um rótulo.
No entanto, ao usar um dicionário, você precisa se lembrar dos nomes das chaves e escrevê-los corretamente sempre que quiser acessar um valor. Isso pode ser propenso a erros e mais difícil de ler, especialmente quando se lida com várias instâncias que têm o mesmo conjunto de campos.
Por outro lado, com namedtuple
, você pode ter os nomes dos campos como atributos de instância e acessá-los diretamente usando a notação de ponto, o que resulta em um código mais limpo e legível.
namedtuple vs Data Class
As data classes são um recurso introduzido no Python 3.7 que simplificam a criação de classes de dados. Elas são úteis quando você precisa implementar métodos personalizados, mas não oferecem recursos avançados de controle de tipos.
As namedtuple
são mais simples de definir e não exigem a importação de um módulo adicional, pois estão disponíveis no módulo collections
do Python. Elas são ideais para casos em que você deseja apenas armazenar dados e acessá-los pelos nomes dos campos, sem a necessidade de adicionar funcionalidades adicionais às instâncias.
namedtuple vs typing.NamedTuple
O módulo typing
do Python introduziu a classe NamedTuple
, que é uma classe genérica que permite definir namedtuples
com tipos de dados especificados. Essa classe é útil quando você precisa fazer anotações de tipo e especificar tipos de dados para os campos da namedtuple
.
No entanto, ao usar typing.NamedTuple
, é necessário importar o módulo typing
e definir explicitamente os tipos de dados dos campos da namedtuple
, o que pode levar a um código mais verboso. Por outro lado, namedtuple
do módulo collections
é mais conciso e mantém a legibilidade do código.
Subclassificando Classes namedtuple
Assim como classes regulares, namedtuples
podem ser subclassificadas para adicionar novos campos ou funcionalidades adicionais. Isso é útil quando você deseja personalizar o comportamento das instâncias de namedtuple
para atender a requisitos específicos.
Veja um exemplo abaixo:
Neste exemplo, criamos a namedtuple
Person
com os campos name
e age
. Em seguida, subclassificamos essa namedtuple
para adicionar o campo city
. Sobrescrevemos o método __new__()
para garantir que o campo city
seja passado corretamente quando uma nova instância for criada. Também adicionamos o método __init__()
para inicializar o novo campo. Em seguida, criamos uma instância da nova namedtuple
NewPerson
e podemos acessar os campos usando a notação de ponto.
Medindo o Tempo de Criação: tuple vs namedtuple
Ao criar muitos objetos, o tempo de criação pode ser um fator importante a ser considerado. Vamos comparar o tempo de criação de tuples
e namedtuples
para ver a diferença.
Veja um exemplo abaixo:
Neste exemplo, usamos a função timeit()
do módulo timeit
para medir o tempo de criação de 100.000 tuples
e 100.000 namedtuples
. Em seguida, imprimimos os tempos de criação medidos.
No geral, namedtuples
tendem a ter um tempo de criação um pouco mais longo em comparação com tuples
. No entanto, a diferença de desempenho pode ser negligenciada na maioria dos casos, a menos que você esteja criando um grande número de objetos. Nesses casos, pode ser necessário fazer mais testes para determinar a melhor escolha.
Conclusão
namedtuple
é uma ferramenta útil no Python que facilita a criação de código Pythonic e limpo. Com a capacidade de acessar valores através de nomes de campo descritivos e a notação de ponto, namedtuple
torna o código mais legível e menos propenso a erros.
Neste tutorial, você aprendeu a criar namedtuple
usando a função namedtuple()
, bem como a explorar recursos adicionais, como criar instâncias a partir de iteráveis, converter instâncias em dicionários, substituir campos em instâncias existentes e acessar atributos adicionais de namedtuple
classes.
Você também comparou namedtuple
com outras estruturas de dados comumente usadas, como dicionários, data classes e typing.NamedTuple
. Além disso, você aprendeu a subclassificar namedtuple
para adicionar funcionalidades adicionais e medir o tempo de criação de namedtuples
em comparação com tuples
.
Com o conhecimento adquirido neste tutorial, você poderá usar namedtuple
para escrever um código mais Pythonic, limpo e legível em seus projetos Python.