Pattern Matching Avançado em Python: Domine Guards, Padrões OR/AND e Evite Armadilhas Comuns

Desde sua introdução oficial na versão 3.10 do Python, o pattern matching trouxe uma maneira estruturada e expressiva de lidar com fluxos condicionais complexos, especialmente ao trabalhar com dados estruturados como tuplas, listas, dicionários ou objetos. Para desenvolvedores experientes, explorar seus recursos avançados—como guards, padrões combinados OR/AND—e compreender suas limitações é fundamental para escrever códigos claros, eficientes e robustos.

Guardas: Condições Dinâmicas para Refinar Combinações

Guards são cláusulas condicionais if adicionadas depois do padrão básico, que só são avaliadas caso o pattern inicial case com o dado. Eles permitem filtrar ainda mais a correspondência com expressões arbitrárias.

Exemplo avançado classificando números com guards para regras detalhadas:

def classificar_numero(x):
    match x:
        case int() if x < 0:
            return "Número inteiro negativo"
        case int() if x == 0:
            return "Zero"
        case int() if x % 2 == 0:
            return "Número inteiro par"
        case int():
            return "Número inteiro ímpar"
        case float() if x.is_integer():
            return "Float que representa um inteiro"
        case float():
            return "Número float"
        case _:
            return "Não é um número"

Guards melhoram a legibilidade evitando ifs aninhados espalhados e permitem separar lógica granular enquanto mantêm a clareza do fluxo de decisão.

Combinações com Padrões OR e AND

Python permite combinar múltiplos padrões num mesmo case usando o operador | (OR). Isso evita duplicação de código quando múltiplos padrões devem resultar na mesma ação.

Exemplo com Enum usando OR para agrupar casos:

from enum import Enum

class Status(Enum):
    OK = 1
    WARNING = 2
    ERROR = 3

def tratar_status(status):
    match status:
        case Status.OK | Status.WARNING:
            print("Status aceitável")
        case Status.ERROR:
            print("Erro detectado")

Não existe operador direto para AND nos padrões; o comportamento AND deve ser implementado via guards, combinando várias condições:

def avaliar_evento(event):
    match event:
        case {"type": "click", "button": btn} if btn in ("left", "right"):
            print(f"Clique {btn} detectado")
        case _:
            print("Outro evento")

Limitações e Armadilhas Técnicas

def processar_tupla(t):
    match t:
        case (x, y) | (y, x) if x == y:
            print("Tupla simétrica")  # NÃO FUNCIONA como esperado
        case _:
            print("Outro caso")

Foi necessário replicar a lógica para casos diferentes ou desestruturar a lógica para manter clareza e correção.

Conclusão

Dominar pattern matching avançado com guards e padrões OR/AND eleva o nível do seu código Python, dando expressividade e eliminando estruturas condicionalmente complexas. Conhecer suas nuances e limitações ajuda a evitar armadilhas comuns que podem levar a bugs difíceis ou código difícil de manter, tornando seu código mais elegante, legível e eficiente diante de fluxos de dados complexos.



Riverfount
Vicente Eduardo Ribeiro Marçal