operator.is_none no Python oferece uma forma funcional e explícita de testar se um valor é exatamente None. Em vez de escrever uma função lambda sempre que uma API espera um callable, você pode usar operator.is_none. O recurso é especialmente útil em filtros, validações, pipelines de transformação, processamento de coleções e código que combina funções de ordem superior.
Este guia explica o comportamento de operator.is_none e operator.is_not_none, mostra exemplos práticos, compara as funções com lambdas e destaca cuidados de compatibilidade. O objetivo não é substituir o uso comum de is None, mas entender quando uma função pronta torna o código mais claro e reutilizável.
Por que testar com is None?
None é um singleton usado para representar ausência de valor, resultado inexistente ou estado ainda não definido. A comparação correta é por identidade:
valor = None
if valor is None:
print("sem valor")
Evite valor == None, pois classes podem personalizar __eq__ e produzir comportamentos inesperados. O operador is verifica se as duas referências apontam para o mesmo objeto.
O que faz operator.is_none?
A função recebe um argumento e retorna True somente quando ele é None. Sua contraparte, operator.is_not_none, retorna True quando o valor não é None.
from operator import is_none, is_not_none
print(is_none(None)) # True
print(is_none(0)) # False
print(is_not_none("")) # True
Valores falsy como zero, string vazia, lista vazia e False não são None. Essa distinção é importante em formulários, APIs e configurações nas quais um valor vazio ainda pode ser válido.
Filtrando valores ausentes
Um uso direto é remover itens None sem eliminar outros valores falsy.
from operator import is_not_none
dados = [10, None, 0, "", None, 25]
validos = list(filter(is_not_none, dados))
print(validos) # [10, 0, '', 25]
Usar apenas filter(None, dados) também removeria zero e string vazia. Portanto, is_not_none comunica uma regra mais precisa.
Separando dados presentes e ausentes
from operator import is_none, is_not_none
respostas = ["sim", None, "não", "", None]
ausentes = list(filter(is_none, respostas))
presentes = list(filter(is_not_none, respostas))
Esse padrão funciona bem em rotinas de limpeza, relatórios de qualidade de dados e validação de campos opcionais.
Uso com any e all
Você também pode combinar a função com geradores para verificar coleções.
from operator import is_none
campos = ["Leandro", "email@example.com", None]
possui_ausente = any(map(is_none, campos))
todos_ausentes = all(map(is_none, campos))
Uma expressão como any(valor is None for valor in campos) continua perfeitamente válida e muitas vezes é mais legível. A função pronta é mais interessante quando o callable precisa ser passado ou armazenado.
Combinando com itertools
Funções pequenas são úteis em pipelines funcionais. Com itertools.filterfalse, por exemplo, é possível inverter um predicado.
from itertools import filterfalse
from operator import is_none
valores = [1, None, 2, None, 3]
presentes = list(filterfalse(is_none, valores))
Nesse caso, filter(is_not_none, valores) é mais direto, mas o exemplo mostra como o predicado pode integrar APIs diferentes.
Comparação com lambda
Antes dessas funções, era comum escrever:
validos = list(filter(lambda item: item is not None, dados))
A lambda funciona e é compatível com versões antigas. A função de operator evita repetição, tem um nome explícito e pode ser importada uma vez para uso em vários pontos. Por outro lado, uma lambda permite regras mais complexas, como verificar None e também validar tipo ou faixa.
Aplicação em registros e dicionários
Em dados estruturados, você pode remover somente chaves cujo valor seja None.
from operator import is_not_none
payload = {
"nome": "Ana",
"idade": None,
"ativo": False,
"apelido": "",
}
limpo = {chave: valor for chave, valor in payload.items() if is_not_none(valor)}
O resultado preserva False e a string vazia. Isso é útil ao montar requisições HTTP, atualizações parciais e documentos para bancos de dados.
Campos opcionais em funções
Ao processar parâmetros opcionais, diferencie ausência de um valor explicitamente vazio.
from operator import is_none
def atualizar(nome=None, ativo=None):
mudancas = {}
if not is_none(nome):
mudancas["nome"] = nome
if not is_none(ativo):
mudancas["ativo"] = ativo
return mudancas
A chamada atualizar(nome="") deve manter a intenção de definir um nome vazio, enquanto atualizar() indica que nada foi informado.
Cuidados com compatibilidade
Antes de adotar o recurso em uma biblioteca, confirme a versão mínima do Python usada pelo projeto. Em ambientes que ainda não oferecem essas funções, mantenha um fallback simples.
try:
from operator import is_none, is_not_none
except ImportError:
def is_none(value):
return value is None
def is_not_none(value):
return value is not None
Em aplicações controladas, declarar a versão mínima no pyproject.toml costuma ser melhor do que espalhar fallbacks.
Desempenho e clareza
Não escolha o recurso apenas por micro-otimização. Em código comum, o custo do teste é pequeno e a legibilidade importa mais. Use valor is None em condicionais diretas. Prefira operator.is_none quando uma função precisa ser passada como argumento, registrada em uma tabela de predicados ou compartilhada entre pipelines.
Testes recomendados
from operator import is_none, is_not_none
assert is_none(None)
assert not is_none(False)
assert not is_none(0)
assert is_not_none("")
assert is_not_none([])
Inclua casos falsy para impedir que uma refatoração troque inadvertidamente a verificação de identidade por uma verificação de verdade.
Boas práticas
Use nomes que expressem a intenção, não confunda ausência com falsidade e documente o significado de None nas interfaces públicas. Em APIs maiores, considere um objeto sentinela próprio quando for necessário distinguir “não informado” de “informado como None”.
Para aprofundar temas relacionados, consulte nossos guias sobre operator no Python, itertools no Python, map, filter e reduce e type hints no Python.
Como referências externas, veja a documentação oficial de operator e a PEP 8, que recomenda comparações com singletons por identidade.
Conclusão
operator.is_none e operator.is_not_none transformam verificações de identidade em callables reutilizáveis. Elas são simples, mas resolvem um problema frequente em filtros e pipelines: distinguir precisamente None de valores falsy válidos. Use as funções quando uma API exigir um predicado; em condicionais comuns, continue preferindo a expressão direta e familiar is None.







