O módulo operator expõe funções eficientes equivalentes aos operadores da linguagem. operator.add(a, b) executa a mesma operação que a + b; operator.getitem(obj, chave) corresponde a obj[chave]; e ferramentas como itemgetter(), attrgetter() e methodcaller() criam callables reutilizáveis para ordenação, agrupamento, mapeamento e composição.
O objetivo não é substituir a sintaxe normal. Em expressões diretas, a + b continua mais legível. O módulo se destaca quando uma API espera uma função: sorted(), map(), reduce(), itertools.groupby(), callbacks e tabelas de operações.
Operadores aritméticos como funções
import operator
print(operator.add(10, 5))
print(operator.sub(10, 5))
print(operator.mul(10, 5))
print(operator.truediv(10, 5))
print(operator.pow(2, 8))Essas funções respeitam os métodos especiais dos objetos. add() pode somar números, concatenar sequências ou executar uma implementação personalizada de __add__().
Usar com reduce
Uma aplicação comum é fornecer uma operação pronta ao functools.reduce().
from functools import reduce
from operator import mul
produto = reduce(mul, [2, 3, 4], 1)
print(produto)Para somas simples, prefira sum(). Use reduce() quando a operação e a identidade estiverem bem definidas e o código permanecer claro.
Comparações como callables
lt, le, eq, ne, ge e gt correspondem às comparações ricas.
comparadores = {
"menor": operator.lt,
"igual": operator.eq,
"maior": operator.gt,
}
resultado = comparadores["maior"](10, 3)Objetos personalizados podem retornar valores que não são booleanos estritos. Quando a API exige True ou False, converta explicitamente com bool().
Identidade e None
is_() e is_not() testam identidade. Python 3.14 adicionou is_none() e is_not_none(), úteis em filtros funcionais.
from operator import is_not_none
valores = [10, None, 20, None, 30]
validos = list(filter(is_not_none, valores))
print(validos)Identidade não é igualdade. Use is ou essas funções para sentinelas como None, e eq() para comparar valores.
Testes de verdade
truth(obj) equivale a bool(obj). not_(obj) equivale a not obj.
ativos = list(filter(operator.truth, [0, 1, "", "ok", [], [1]]))Filtros por verdade removem zero, coleções vazias, strings vazias e None ao mesmo tempo. Não use essa técnica quando zero ou vazio forem valores válidos.
itemgetter para dicionários, tuplas e listas
itemgetter() cria uma função que chama __getitem__(). É muito usado como chave de ordenação.
from operator import itemgetter
produtos = [
{"nome": "A", "preco": 30},
{"nome": "B", "preco": 10},
{"nome": "C", "preco": 20},
]
ordenados = sorted(produtos, key=itemgetter("preco"))Vários itens produzem uma tupla e permitem ordenação por múltiplos campos.
chave = itemgetter("categoria", "preco")Fatias com itemgetter
O argumento pode ser qualquer chave aceita pelo objeto, inclusive um slice.
ultimos = itemgetter(slice(-3, None))
print(ultimos([1, 2, 3, 4, 5]))Essa técnica pode ser elegante em pipelines, mas uma função nomeada é melhor quando a transformação precisa de validação ou documentação.
attrgetter para atributos
attrgetter() acessa um ou vários atributos e aceita caminhos com pontos.
from operator import attrgetter
usuarios_ordenados = sorted(usuarios, key=attrgetter("perfil.nome"))
O acesso segue cada atributo em sequência. Se algum não existir, a exceção correspondente será propagada. Para valores opcionais, escreva uma função que trate o caso explicitamente.
methodcaller para chamar métodos
methodcaller() cria uma função que chama um método com argumentos definidos.
from operator import methodcaller
nomes = [" Ana ", " BRUNO", "carla "]
limpos = list(map(methodcaller("strip"), nomes))
minusculos = list(map(methodcaller("lower"), limpos))Ele também aceita argumentos posicionais e nomeados. Não use nomes de métodos fornecidos por usuários sem uma lista permitida, pois isso amplia a superfície de comportamento.
operator.call
Desde Python 3.11, call(obj, *args, **kwargs) chama um callable. Pode ser útil em pipelines homogêneos.
tarefas = [lambda: "A", lambda: "B"]
resultados = list(map(operator.call, tarefas))Em código comum, func() é mais legível. A função faz sentido quando a chamada precisa ser passada como valor.
Operações em sequências
contains(a, b) executa b in a; observe a ordem invertida. countOf() conta ocorrências, indexOf() encontra o primeiro índice e concat() concatena sequências.
print(operator.contains([1, 2, 3], 2))
print(operator.countOf("banana", "a"))
print(operator.indexOf([10, 20, 30], 20))A ordem de contains() é uma fonte comum de erro.
getitem, setitem e delitem
Essas funções acessam e modificam itens de maneira genérica.
dados = {"ativo": False}
operator.setitem(dados, "ativo", True)
print(operator.getitem(dados, "ativo"))
operator.delitem(dados, "ativo")Elas são úteis em tabelas de comandos e abstrações, mas a sintaxe direta costuma ser preferível quando a chave é conhecida.
length_hint
length_hint() tenta obter o comprimento real ou uma estimativa de um iterável.
iterador = iter(range(100))
estimativa = operator.length_hint(iterador)O resultado é apenas uma dica para pré-alocação. Não use como quantidade confiável de itens nem como condição de segurança.
Operações bit a bit e matrizes
O módulo inclui and_(), or_(), xor(), invert(), deslocamentos e matmul(). Os nomes and_ e or_ evitam conflito com palavras reservadas.
Essas funções invocam os mesmos métodos especiais que a sintaxe, portanto podem operar em sets, arrays e objetos de bibliotecas numéricas.
Operações in-place
iadd(), imul() e outras funções chamam operações in-place. Para objetos mutáveis, podem modificar o argumento. Para imutáveis, retornam um novo valor, mas não atualizam a variável do chamador.
texto = "Olá"
novo = operator.iadd(texto, " mundo")
print(texto) # continua igual
lista = [1, 2]
operator.iadd(lista, [3])
print(lista) # foi alteradaEssa diferença exige cuidado em código genérico. Sempre use o valor retornado quando não souber se o objeto é mutável.
Tabela segura de operações
OPERACOES = {
"+": operator.add,
"-": operator.sub,
"*": operator.mul,
"/": operator.truediv,
}
def calcular(a, simbolo, b):
try:
funcao = OPERACOES[simbolo]
except KeyError:
raise ValueError("operação não permitida")
return funcao(a, b)Uma tabela explícita é mais segura que eval(). Ainda valide tipos, divisão por zero, limites numéricos e custo da operação.
Desempenho e legibilidade
itemgetter() e attrgetter() são implementações eficientes, mas a diferença para lambdas geralmente não deve ser a primeira preocupação. Escolha a forma que comunica melhor a regra.
Uma lambda é melhor quando há transformação, fallback ou lógica. Um getter é ótimo para acesso direto e declarativo.
Erros frequentes
- Usar o módulo em expressões onde a sintaxe direta é mais clara.
- Inverter os argumentos de
contains(). - Confundir identidade com igualdade.
- Descartar o retorno de uma operação in-place em objeto imutável.
- Usar
truth()e remover zeros válidos. - Acessar atributos opcionais sem tratamento.
- Construir uma calculadora com
eval()em vez de uma tabela permitida.
Boas práticas
- Use getters como chaves de ordenação e agrupamento.
- Prefira funções nomeadas quando houver lógica.
- Valide operações selecionadas por usuários.
- Preserve o retorno das funções in-place.
- Use identidade apenas para sentinelas.
- Teste objetos personalizados e exceções.
- Priorize clareza antes de micro-otimizações.
Conteúdos relacionados
Veja bisect, statistics, fractions, Decimal e inspect.
Consulte a documentação oficial do operator e a documentação do functools.
Conclusão
O módulo operator transforma operações da linguagem em valores chamáveis, o que simplifica ordenações, agrupamentos, mapeamentos e tabelas de comportamento. Ele é mais útil em APIs funcionais; em expressões comuns, a sintaxe nativa continua sendo a opção mais clara.







