UserList no Python: listas customizadas

Publicado em: 30/08/2026
Tempo de leitura: 3 minutos
A laptop screen showing a code editor with visible programming code in a dimly lit environment.

collections.UserList é uma classe auxiliar para criar sequências mutáveis personalizadas. Ela armazena os elementos em uma lista comum disponível no atributo data e oferece uma base mais previsível para validação, normalização, logging e regras de domínio do que a herança direta de list.

O recurso é útil quando uma coleção precisa continuar se comportando como lista, mas deve controlar inserções, remoções, tipos aceitos ou operações em lote.

Primeiro exemplo

from collections import UserList

class ListaInteiros(UserList):
    def _validar(self, valor):
        if not isinstance(valor, int):
            raise TypeError("apenas inteiros")
        return valor

    def append(self, valor):
        super().append(self._validar(valor))

    def insert(self, indice, valor):
        super().insert(indice, self._validar(valor))

Validar somente append não basta. A lista também pode mudar por insert, atribuição por índice, slices, extend e +=.

Validando todas as mutações

class ListaInteiros(UserList):
    def _validar(self, valor):
        if not isinstance(valor, int):
            raise TypeError("apenas inteiros")
        return valor

    def __setitem__(self, indice, valor):
        if isinstance(indice, slice):
            valor = [self._validar(item) for item in valor]
        else:
            valor = self._validar(valor)
        super().__setitem__(indice, valor)

    def append(self, valor):
        super().append(self._validar(valor))

    def insert(self, indice, valor):
        super().insert(indice, self._validar(valor))

    def extend(self, valores):
        super().extend(self._validar(item) for item in valores)

Centralizar a regra em um método privado reduz inconsistências.

O atributo data

lista = ListaInteiros([1, 2, 3])
print(lista.data)

data contém a lista real. Modificá-la diretamente pode ignorar validações, portanto trate o atributo como detalhe de implementação.

Normalização de valores

class Tags(UserList):
    def _normalizar(self, valor):
        texto = str(valor).strip().casefold()
        if not texto:
            raise ValueError("tag vazia")
        return texto

Decida se duplicatas são permitidas. Se a unicidade for a regra principal, um conjunto ou mapping pode representar melhor o domínio.

UserList versus list

Uma subclasse direta de list pode oferecer desempenho melhor e é necessária quando uma API exige exatamente esse tipo. UserList prioriza extensibilidade e encaminha operações para métodos Python mais fáceis de sobrescrever.

UserList versus MutableSequence

Implemente collections.abc.MutableSequence quando o armazenamento não for uma lista normal, como uma sequência em disco, janela virtual ou estrutura compacta. Use UserList quando uma lista interna for suficiente.

Operações que retornam novas listas

Teste soma, multiplicação, slicing e cópia. Dependendo do comportamento desejado, o resultado pode ser uma instância da classe personalizada ou uma lista comum. Defina isso como parte da API.

Ordenação

class Tarefas(UserList):
    def sort(self, *, key=None, reverse=False):
        registrar("ordenando tarefas")
        super().sort(key=key, reverse=reverse)

Evite adicionar efeitos colaterais caros ou surpreendentes a métodos familiares.

Imutabilidade depois de congelar

class ListaCongelavel(UserList):
    congelada = False

    def _verificar(self):
        if self.congelada:
            raise TypeError("lista congelada")

    def append(self, valor):
        self._verificar()
        super().append(valor)

Para imutabilidade permanente, uma tupla pode ser mais adequada.

Serialização

Algumas bibliotecas exigem uma lista concreta. Converta explicitamente:

import json
json.dumps(list(lista), ensure_ascii=False)

Erros comuns

  • Validar apenas append.
  • Esquecer atribuição por slice e extend.
  • Modificar data diretamente.
  • Usar uma lista quando o domínio exige unicidade.
  • Presumir o tipo retornado por soma, slicing ou cópia.

Boas práticas

Liste todas as operações mutáveis, centralize validação, use super(), teste os operadores e documente o tipo de retorno. Veja também os artigos internos sobre listas no Python e collections.

Conclusão

UserList é uma base útil para sequências personalizadas respaldadas por uma lista comum. Ela facilita invariantes consistentes sem depender dos detalhes internos de list.

Fontes externas

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Conteúdo do artigo

    Artigos relacionados

    Close-up of a person underlining text in a dictionary on a desk with a laptop.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    UserDict no Python: dicionários customizados

    Aprenda UserDict no Python para criar dicionários customizados com validação, normalização, composição e APIs previsíveis.

    Ler mais

    Tempo de leitura: 3 minutos
    30/08/2026
    High-angle view of woman coding on a laptop, with a Python book nearby. Ideal for programming and tech content.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    itertools.accumulate: somas e estados cumulativos

    Aprenda itertools.accumulate no Python para somas, saldos, máximos progressivos e estados cumulativos em pipelines eficientes.

    Ler mais

    Tempo de leitura: 3 minutos
    30/08/2026
    A person reads 'Python for Unix and Linux System Administration' indoors.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    itertools.groupby: agrupe dados ordenados corretamente

    Aprenda itertools.groupby no Python para agrupar dados ordenados, agregar streams e evitar erros com subiteradores compartilhados.

    Ler mais

    Tempo de leitura: 3 minutos
    30/08/2026
    High-angle view of woman coding on a laptop, with a Python book nearby. Ideal for programming and tech content.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    contextlib.chdir: riscos ao trocar diretórios

    Aprenda contextlib.chdir no Python, seus riscos com estado global e concorrência e quando preferir pathlib ou subprocess cwd.

    Ler mais

    Tempo de leitura: 3 minutos
    30/08/2026
    A person typing on a laptop with a Python programming book visible, capturing technology and learning.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    nullcontext no Python: contextos opcionais

    Use nullcontext no Python para unificar contextos opcionais, recursos já abertos, locks e transações sem duplicar código.

    Ler mais

    Tempo de leitura: 5 minutos
    30/08/2026
    Close-up view of a computer screen displaying code in a software development environment.
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    contextlib.aclosing: feche geradores async

    Aprenda contextlib.aclosing no Python para fechar geradores assíncronos em break, return, exceções e cancelamentos com segurança.

    Ler mais

    Tempo de leitura: 5 minutos
    30/08/2026