🎯 Correspondência de Padrões em Python
Em poucas palavras
Definição técnica ou simplificada do conceito.
📝 Notas e Desenvolvimento
🔗 Conexões e Contexto
- Atlas: MdC - Programação
- Notas Relacionadas:
📚 Referências e Fontes
Links Externos
Citações Diretas
📂 Outros Conteúdos Preservados
Sintaxe Básica
A correspondência de padrões utiliza a declaração match seguida por uma série de blocos case.
match <expressao>:
case <padrao_1>:
# Código a ser executado se a expressão corresponder ao padrao_1
case <padrao_2>:
# Código a ser executado se a expressão corresponder ao padrao_2
case _: # Padrão curinga (wildcard)
# Código a ser executado se a expressão não corresponder a nenhum dos padrões anteriores<expressao>: O valor que está sendo comparado.<padrao>: A estrutura ou valor com o qual a expressão é comparada._: O padrão curinga, que corresponde a qualquer coisa e é útil para capturar casos padrão ou ignorar partes de um padrão.
Tipos de Padrões
A correspondência de padrões é muito flexível e pode lidar com vários tipos de padrões:
-
Padrões Literais: Correspondem a valores exatos.
status_code = 200 match status_code: case 200: print("OK") case 404: print("Não encontrado") case _: print("Outro status") # Saída: OK -
Padrões de Sequência: Desestruturam listas, tuplas e outras sequências.
ponto = (10, 20) match ponto: case (x, y): print(f"Ponto em x={x}, y={y}") case _: print("Não é um ponto 2D") # Saída: Ponto em x=10, y=20Isso é uma extensão poderosa do Desempacotar sequencias em Python.
-
Padrões de Mapeamento: Desestruturam dicionários.
usuario = {'nome': 'Alice', 'idade': 30} match usuario: case {'nome': n, 'idade': i}: print(f"Nome: {n}, Idade: {i}") case _: print("Formato de usuário desconhecido") # Saída: Nome: Alice, Idade: 30 -
Padrões de Classe: Correspondem a instâncias de classes e seus atributos.
class Ponto: def __init__(self, x, y): self.x = x self.y = y p = Ponto(5, 10) match p: case Ponto(x=val_x, y=val_y): print(f"Objeto Ponto com x={val_x}, y={val_y}") case _: print("Não é um objeto Ponto") # Saída: Objeto Ponto com x=5, y=10 -
Padrões de Captura: Atribuem o valor correspondente a uma variável.
valor = "hello" match valor: case msg: # 'msg' captura o valor de 'valor' print(f"Capturado: {msg}") # Saída: Capturado: hello -
Padrões
as: Capturam um subpadrão.coordenada = (1, 2, 3) match coordenada: case (x, y, z) as ponto_3d: print(f"Ponto 3D: {ponto_3d}, x={x}, y={y}, z={z}") # Saída: Ponto 3D: (1, 2, 3), x=1, y=2, z=3 -
Padrões
OR: Combinam múltiplos padrões com|.dia = "Sábado" match dia: case "Sábado" | "Domingo": print("É fim de semana!") case _: print("É dia de semana.") # Saída: É fim de semana! -
Guards (
if): Adicionam condições adicionais aos padrões.idade = 18 match idade: case i if i < 18: print("Menor de idade") case i if i >= 18: print("Maior de idade") # Saída: Maior de idade
Exemplos Práticos
Exemplo 1: Processamento de Comandos Simples
def processar_comando(comando):
match comando.split():
case ["get", obj]:
print(f"Pegando o {obj}.")
case ["swing", obj]:
print(f"Balançando o {obj}! AHHHH!")
case ["abrir", "porta", direcao] if direcao in ["norte", "sul", "leste", "oeste"]:
print(f"Abrindo a porta para o {direcao}.")
case _: # Curinga para qualquer outro caso de correspondência
raise ValueError(f"Não sei como '{comando}'")
processar_comando("swing espada")
### Saída: Balançando o espada! AHHHH!
processar_comando("get chave")
### Saída: Pegando o chave.
processar_comando("abrir porta norte")
### Saída: Abrindo a porta para o norte.
### processar_comando("correr rápido")
### Levantaria ValueError: Não sei como 'correr rápido'
Exemplo 2: Desestruturação de Dados Complexos com Condições
Este exemplo demonstra como desestruturar dados aninhados e aplicar condições (if) para filtrar resultados, similar ao que se faria com Desempacotar sequencias em Python e lógica condicional, mas de forma mais integrada.
metro_areas = [
('Tokyo', 'JP', 36.933, (35.689722, 139.691667)),
('Delhi NCR', 'IN', 21.935, (28.613889, 77.208889)),
('Mexico City', 'MX', 20.142, (19.433333, -99.133333)),
('New York-Newark', 'US', 20.104, (40.808611, -74.020386)),
('São Paulo', 'BR', 19.649, (-23.547778, -46.635833)),
]
print(f'{"Cidade":15} | {"Latitude":>9} | {"Longitude":>9}')
print("-" * 40)
for record in metro_areas:
match record:
# Padrão de sequência: [nome, _, _, (lat, lon)]
# O '_' ignora os elementos 'código do país' e 'população'.
# O padrão aninhado '(lat, lon)' desestrutura a tupla de coordenadas.
# A guarda 'if lon <= 0' filtra apenas as cidades no hemisfério ocidental.
case [name, _, _, (lat, lon)] if lon <= 0:
print(f'{name:15} | {lat:9.4f} | {lon:9.4f}')
case _:
# Este caso pode ser usado para lidar com outros formatos de registro
# ou para ignorar registros que não correspondem ao critério.
pass
### Saída:
### Cidade | Latitude | Longitude
### ----------------------------------------
### Mexico City | 19.4333 | -99.1333
### New York-Newark | 40.8086 | -74.0204
### São Paulo | -23.5478 | -46.6358
A correspondência de padrões em Python é uma ferramenta poderosa para escrever código mais limpo e expressivo, especialmente ao lidar com estruturas de dados complexas ou múltiplas condições.
:: Referência :: PEP 634 – Structural Pattern Matching: Specification