Optional, Union e o Operador |
Unions expressam valores que podem assumir múltiplos tipos. A sintaxe X | Y (3.10+) substitui Union[X, Y]; tipos anuláveis são uniões com None.
Receita
def parse_count(raw: str | None) -> int:
if raw is None:
return 0
return int(raw)
def format_id(value: int | str) -> str:
return str(value)Quando usar isso:
- Análise de variáveis de configuração e ambiente opcionais
- Funções que retornam "valor ou ausente"
- Aceitação de múltiplas representações de entrada
- Modelagem de sucesso/falha sem exceções
Exemplo de Trabalho
from dataclasses import dataclass
@dataclass
class User:
id: int
email: str | None
def email_domain(user: User) -> str | None:
if user.email is None:
return None
return user.email.split("@", 1)[1]
def describe(value: int | str | None) -> str:
match value:
case None:
return "ausente"
case int(n):
return f"número {n}"
case str(s):
return f"texto {s}"
def coalesce(*values: str | None) -> str:
for v in values:
if v is not None:
return v
return ""
if __name__ == "__main__":
print(describe(42))
print(email_domain(User(1, None)))O que isso demonstra:
is None/is not Noneestreita tipos opcionais para verificadoresmatch/casecom padrões tipados refina uniõesstr | Noneem argumentos variádicos para cadeias de fallback- Retornando
Noneexplicitamente no tipo de retorno
Aprofundamento
Como Funciona
- Union - O valor pode ser qualquer tipo membro; o verificador exige o tratamento de todos os casos.
- Narrowing - Refinamentos de fluxo de controle encolhem a união para um membro específico.
- Alias Optional -
Optional[T]significaT | None- ainda válido,|é o estilo preferido. - Exaustividade -
mypy --strictavisa sobre membros de união não tratados emmatch. - TypeGuard - Funções que estreitam tipos para chamadores (avançado).
Ferramentas de Narrowing
| Ferramenta | Exemplo |
|---|---|
is None | Optional -> T |
isinstance | Membros da Union |
match/case | Estrutural + tipos |
assert | Dica apenas para o verificador |
Notas de Python
from typing import TypeGuard
def is_str_list(val: list[object]) -> TypeGuard[list[str]]:
return all(isinstance(x, str) for x in val)Armadilhas
- Verificação de truthy vs None -
if email:trata a string vazia como ausente de forma diferente deis None. Correção: Escolha semântica explícita deNonevs. falsy. - Uso excessivo de Optional - Tudo
T | Noneobscurece campos obrigatórios. Correção: Separar campos de modelo obrigatórios e opcionais. - Ordem da Union - Geralmente irrelevante; os verificadores tratam simetricamente.
- Retornando Any de um branch de union - Amplia o resultado. Correção: Tipo de retorno consistente por branch.
- JSON null - Mapeia para
Noneem Python - valide na fronteira com Pydantic.
Alternativas
| Alternativa | Usar Quando | Não Usar Quando |
|---|---|---|
Tipos Result/Either | Canal de erro explícito | Exceções são idiomáticas |
Literal | Conjunto fixo de valores | Tipos de finalidade aberta |
| exceções | Falta verdadeiramente excepcional | Campo opcional esperado |
| objeto sentinela | Distinguir ausente vs None | Optional mais simples é suficiente |
FAQs
Optional ou `|` None?
Mesmo significado - prefira str | None em bases de código Python 3.10+ modernas.
como estreitar union?
isinstance, match, igualdade a None, ou funções TypeGuard.
Union em isinstance?
isinstance(x, (int, str)) é válido em tempo de execução; o verificador estreita de acordo.
campo dataclass opcional?
field: str | None = None ou Optional com padrão None.
PEP 604 `|` com None?
int | None substitui Optional[int] - leitura mais limpa.
match exaustivo?
Inclua case _: ou mypy pode avisar sobre union não tratada em configurações estritas.
union de modelos?
User | Admin com Protocol compartilhado ou classe base para campos comuns.
None em API JSON?
Campos Optional do Pydantic mapeiam para null; documente nullable do OpenAPI cuidadosamente.
assert para verificador?
assert x is not None estreita para mypy - sem operação em tempo de execução se otimizações removerem asserts (-O).
muitas unions?
Refatore para classe base, Protocol, ou union discriminada com campo de tag literal.
Relacionado
- Fundamentos de Type Hints - fundamentos
- Literal, Final & Annotated - unions precisas
- TypedDict & NamedTuple - chaves opcionais
- Fluxo de Controle - narrowing de match
Versões da Pilha: Esta página foi escrita para Python 3.14.0 (estável 3.14, manutenção 3.13), FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+ e uv 0.6+.