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

    Estrutura de código e XML para canonicalização com Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    ElementTree canonicalize: normalize XML no Python

    Aprenda ElementTree canonicalize no Python para comparar XML, gerar hashes estáveis e controlar namespaces, espaços e comentários.

    Ler mais

    Tempo de leitura: 5 minutos
    22/10/2026
    Código de programação Python em uma tela
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    T-strings e templatelib: interpolação estruturada

    Aprenda t-strings e string.templatelib no Python para processar interpolações, criar renderizadores seguros e preservar dados estruturados.

    Ler mais

    Tempo de leitura: 6 minutos
    22/10/2026
    Banco SQLite e código Python para exportação seletiva com iterdump
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    SQLite iterdump: crie dumps seletivos no Python

    Aprenda sqlite3.Connection.iterdump com filtro para gerar dumps seletivos, validar dependências e restaurar bancos com segurança.

    Ler mais

    Tempo de leitura: 5 minutos
    21/10/2026
    Código e arquivos representando compressão de dados no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    compression.zstd: Zstandard rápido no Python

    Aprenda a usar compression.zstd no Python para comprimir e descomprimir dados com desempenho, streaming e segurança.

    Ler mais

    Tempo de leitura: 7 minutos
    21/10/2026
    Arquivo de configuração e estrutura de código para ConfigParser no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    ConfigParser: leia INI sem seção no Python

    Aprenda a ler arquivos INI sem cabeçalho usando ConfigParser, com validação, tipos, compatibilidade e escrita segura.

    Ler mais

    Tempo de leitura: 5 minutos
    20/10/2026
    Dados binários e memória de computador representando memoryview no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    memoryview count e index: busque sem copiar

    Aprenda memoryview count e index no Python para buscar valores em buffers sem cópias e validar dados binários com eficiência.

    Ler mais

    Tempo de leitura: 5 minutos
    20/10/2026