operator.is_none é uma função do módulo operator criada para testar se um valor é exatamente None. Embora a expressão x is None continue sendo a forma mais direta em condições comuns, uma função pronta é especialmente útil quando o teste precisa ser passado como argumento para filter, map, pipelines funcionais, APIs de ordenação ou ferramentas que recebem callables.
Neste guia, você aprenderá como usar operator.is_none, quando ela melhora a legibilidade, como combinar o recurso com iteradores, como manter compatibilidade com versões anteriores do Python e quais erros evitar ao trabalhar com valores ausentes.
O que operator.is_none faz?
A função recebe um objeto e retorna True somente quando esse objeto é o singleton None. Ela não usa igualdade e não considera valores falsos equivalentes. Assim, zero, string vazia, lista vazia e False continuam retornando False.
from operator import is_none
print(is_none(None)) # True
print(is_none(0)) # False
print(is_none(False)) # False
print(is_none("")) # False
Essa diferença é importante porque None normalmente representa ausência de valor, enquanto outros objetos falsos podem ser dados válidos. Um contador igual a zero, por exemplo, não deve ser descartado apenas porque sua conversão booleana é falsa.
Por que não usar apenas uma lambda?
Antes dessa função, era comum escrever lambda valor: valor is None. A lambda funciona, mas repete uma intenção frequente e adiciona ruído visual. Uma função nomeada comunica melhor o propósito, pode ser reutilizada e evita a criação de pequenas funções anônimas espalhadas pelo código.
valores = [10, None, 0, None, 25]
nulos = list(filter(is_none, valores))
print(nulos) # [None, None]
O ganho é maior em pipelines com várias etapas. Ao ler filter(is_none, valores), fica imediatamente claro que o filtro seleciona os itens ausentes.
Removendo valores None
Para manter apenas os valores presentes, combine is_none com itertools.filterfalse. Essa solução preserva zero, False e coleções vazias, ao contrário de filter(None, valores), que remove qualquer item falso.
from itertools import filterfalse
from operator import is_none
valores = [0, None, "", 8, False, None]
presentes = list(filterfalse(is_none, valores))
print(presentes) # [0, "", 8, False]
Esse padrão é útil ao limpar dados vindos de formulários, APIs e bancos de dados. Ele evita perder informações legítimas durante a normalização.
Uso com dados de APIs
Imagine uma API que devolve preços opcionais. Um preço igual a zero pode representar uma promoção gratuita, enquanto None significa que o preço ainda não foi informado. O teste explícito permite manter essa distinção.
from itertools import filterfalse
from operator import is_none
precos = [19.90, None, 0.0, 49.90]
precos_informados = list(filterfalse(is_none, precos))
print(precos_informados)
Em aplicações reais, documente o significado de None. O mesmo valor pode representar campo ausente, resultado desconhecido, operação não executada ou falha recuperável.
Separando valores presentes e ausentes
Quando você precisa das duas coleções, uma única passagem explícita costuma ser mais eficiente e legível. Ainda assim, is_none pode centralizar a regra e evitar diferenças entre módulos.
from operator import is_none
presentes = []
ausentes = []
for item in [1, None, 2, None, 0]:
destino = ausentes if is_none(item) else presentes
destino.append(item)
Essa abordagem também permite registrar métricas, identificar a posição dos valores ausentes ou aplicar tratamentos diferentes conforme a origem do dado.
Compatibilidade entre versões
Antes de adotar a função em uma biblioteca, confirme a versão mínima do Python suportada. Para projetos que também rodam em versões sem operator.is_none, forneça um fallback simples.
try:
from operator import is_none
except ImportError:
def is_none(value):
return value is None
O fallback mantém a mesma semântica e permite usar um único nome no restante do projeto. Em aplicações internas, outra opção é elevar a versão mínima e remover o código de compatibilidade.
Não confunda identidade com igualdade
O teste correto para None usa identidade. Escrever valor == None pode chamar um método __eq__ personalizado e produzir resultados inesperados. operator.is_none segue a mesma semântica de valor is None, sem delegar a comparação ao objeto.
class Estranho:
def __eq__(self, other):
return True
obj = Estranho()
print(obj == None) # pode retornar True
print(is_none(obj)) # False
Essa previsibilidade é importante em código que recebe objetos de bibliotecas externas, arrays, proxies ou modelos com operadores sobrecarregados.
Quando a expressão is None ainda é melhor?
Dentro de um if, a expressão tradicional geralmente é mais clara. Não há vantagem em substituir if resultado is None: por if is_none(resultado): sem um motivo específico. A função é mais valiosa quando você precisa de um callable de primeira classe.
resultado = obter_resultado()
if resultado is None:
tratar_ausencia()
Use cada forma no contexto em que comunica melhor a intenção. O objetivo não é trocar todas as verificações existentes, mas evitar lambdas repetitivas e filtros incorretos.
Pipelines e composição
Em pipelines funcionais, predicados nomeados facilitam composição, testes e instrumentação. Você pode combinar is_none com geradores para processar grandes volumes sem carregar tudo na memória.
from itertools import filterfalse
from operator import is_none
linhas = (parse_linha(linha) for linha in arquivo)
validas = filterfalse(is_none, linhas)
for registro in validas:
salvar(registro)
Nesse exemplo, parse_linha pode devolver None para linhas ignoradas. O pipeline remove somente essas ocorrências e mantém registros falsos que sejam válidos por domínio.
Tipagem estática
Ferramentas de tipagem podem não estreitar automaticamente um tipo opcional depois de um filtro genérico. Dependendo do analisador, talvez seja necessário usar uma função com anotação TypeGuard ou adicionar uma anotação explícita. Portanto, is_none resolve a lógica em tempo de execução, mas não substitui todo refinamento de tipos.
Para aprofundar esse assunto, consulte o guia de type hints no Python e o artigo sobre typing.ReadOnly. Também vale revisar funções lambda e iteradores e geradores.
Testes recomendados
Inclua casos com None, zero, False, string vazia, coleções vazias e objetos personalizados. Esses testes documentam que a regra trata ausência por identidade e protege contra futuras simplificações incorretas.
def test_is_none():
assert is_none(None)
assert not is_none(0)
assert not is_none(False)
assert not is_none("")
assert not is_none([])
Boas práticas
Use is_none quando uma API espera uma função; prefira is None em condições diretas; não use filter(None, dados) quando valores falsos são válidos; documente o significado de ausência; e mantenha um fallback apenas enquanto versões antigas precisarem ser suportadas.
A documentação oficial do módulo operator apresenta as funções disponíveis na versão instalada. Para entender a semântica de comparações e identidade, consulte também o referencial de expressões do Python.
Conclusão
operator.is_none é uma função pequena, mas útil para tornar filtros e pipelines mais explícitos. Ela seleciona somente o singleton None, preserva outros valores falsos e elimina lambdas repetitivas. Ao usá-la junto com filterfalse, você pode limpar dados opcionais sem descartar zeros, strings vazias ou booleanos válidos. A adoção deve considerar a versão mínima do Python, a interação com tipagem estática e a clareza do contexto. Em condições simples, continue usando is None; quando precisar passar o predicado como objeto, operator.is_none oferece uma solução direta e reutilizável.







