Python’da Modern Veri Ayrıştırma: Yapısal Pattern Matching (match-case)

Bir e-ticaret sisteminin arka planında çalıştığınızı hayal edin. Sisteme gelen komutlar bazen basit bir “ÇIKIŞ” metni, bazen bir ürün ekleme listesi ["ekle", "Laptop", 2], bazen ise detaylı bir sipariş nesnesi şeklinde geliyor. Eskiden bu karmaşık yapıyı yönetmek için iç içe geçmiş onlarca if-elif-else bloğu yazmak zorundaydık. Peki, Python 3.10 ile gelen ve kodumuzu çok daha okunaklı hale getiren “Structural Pattern Matching” (Yapısal Desen Eşleme) ile bunu nasıl daha zarif bir şekilde çözeriz?

Karmaşık Veri Akışlarını Yöneten Bir Komut İşleyici

Bu projede, gerçek dünya senaryolarına uygun bir komut işleme (command processing) mimarisi kurguladık. Uygulamanın temel amacı, farklı veri tiplerinde (string, liste, sözlük ve nesne) gelen girişleri analiz etmek ve her birine uygun işlemi gerçekleştirmektir.

Geleneksel yöntemlerde her bir veri tipini isinstance() ile kontrol edip ardından içeriğini sorgulardık. Ancak match-case yapısı, hem verinin tipini hem de yapısını aynı anda kontrol etmemize olanak tanıyarak kodun hem performansını hem de okunabilirliğini artırıyor.

Kodun Anatomisi

Projenin kalbi, process_command fonksiyonunda yatıyor. Burada Python’un sunduğu altı farklı eşleme stratejisini kullandık:

  1. Literal Matching (Sabit Değer Eşleme): Basit metinler için kullanılır. Örneğin, "EXIT" komutu geldiğinde sistemi kapatma işlemini tetikler.
  2. Sequence Matching (Sıralı Yapı Eşleme): Listelerin hem uzunluğunu hem de içindeki elemanların tipini kontrol eder. ["add", str(item), int(qty)] deseni, listenin tam olarak üç elemanlı olduğunu ve ikinci ile üçüncü elemanın sırasıyla metin ve sayı olduğunu doğrular.
  3. Guard Expressions (Koruma İfadeleri): Desen eşleşse bile ek bir koşul aranmasıdır. ["delete", *id_list] if len(id_list) > 0 örneğinde, liste “delete” ile başlasa bile, silinecek ID listesinin boş olmaması şartı aranır.
  4. Object Matching (Nesne Eşleme): @dataclass ile tanımlanmış sınıfları analiz eder. Sadece Order tipindeki nesneleri değil, aynı zamanda bu nesnenin status özniteliğinin "shipped" olduğu durumları özel olarak yakalayabiliriz.
  5. Mapping Matching (Sözlük Eşleme): Sözlüklerin içindeki anahtar-değer çiftlerini kontrol eder. {"type": "invoice", "amount": float(amt)} deseni, sözlükte mutlaka bu anahtarların olması gerektiğini ve tutarın ondalıklı sayı olması gerektiğini belirtir.
  6. Wildcard (Joker Karakter): case _: ifadesi, yukarıdaki hiçbir desene uymayan tüm hatalı veya bilinmeyen girişleri yakalayan bir “güvenlik ağı” görevi görür.
from dataclasses import dataclass

@dataclass
class Order:
    product_name: str
    quantity: int
    status: str  # "pending", "shipped", "delivered"

def process_command(command):
    match command:
        # Sabit değer kontrolü
        case "EXIT":
            print("Sistemden çıkılıyor...")
            return False

        # Liste yapısı ve tip kontrolü: ["add", "Kitap", 3]
        case ["add", str(item), int(qty)]:
            print(f"Stok güncellendi: {qty} adet '{item}' eklendi.")

        # Guard kullanımı: Liste boş değilse sil
        case ["delete", *id_list] if len(id_list) > 0:
            print(f"Şu ID'li ürünler siliniyor: {id_list}")

        # Dataclass nesne kontrolü (Sadece gönderilenler)
        case Order(product_name=name, quantity=qty, status="shipped"):
            print(f"Yolda: {name} ({qty} adet) kurye ile iletiliyor.")

        # Tüm Order nesneleri için genel yakalayıcı
        case Order() as order:
            print(f"Genel Sipariş Bilgisi: {order.product_name} - Durum: {order.status}")

        # Sözlük yapısı kontrolü
        case {"type": "invoice", "amount": float(amt)}:
            print(f"Fatura işlendi. Tutar: ${amt:.2f}")

        # Hatalı veya tanınmayan formatlar
        case _:
            print(f"Geçersiz komut formatı: {command}")

    return True

# Test senaryoları
if __name__ == "__main__":
    test_payloads = [
        ["add", "Laptop", 2],
        ["delete", 404, 505],
        Order("Kablosuz Kulaklık", 1, "shipped"),
        Order("Kahve Makinesi", 1, "pending"),
        {"type": "invoice", "amount": 1250.50},
        ["hatali_format"], 
        "EXIT"
    ]

    for payload in test_payloads:
        process_command(payload)

Nasıl Çalıştırılır?

Bu proje herhangi bir dış kütüphane gerektirmez, sadece standart Python 3.10+ yüklü olması yeterlidir.

  1. Dosyayı main.py olarak kaydedin.
  2. Terminalinizde şu komutu çalıştırın:
    bash python main.py

Ne Öğrendik?

Bu çalışma ile Python’un modern kontrol akış yapılarını deneyimledik:

  • Kod Temizliği: Karmaşık if-elif bloklarını daha deklaratif bir yapıya dönüştürdük.
  • Tip Güvenliği: Desenler içerisinde str() veya int() kullanarak çalışma zamanında tip doğrulaması yaptık.
  • Esneklik: *id_list gibi yapısal açılımlarla değişken uzunluktaki verileri kolayca yakaladık.
  • Sınıf Entegrasyonu: Dataclass’ların yapısal eşleme ile ne kadar uyumlu çalıştığını gördük.

Kaynaklar ve Sonraki Adımlar

Structural Pattern Matching hakkında daha fazla bilgi edinmek için Python’un resmi PEP 634 dökümanını inceleyebilirsiniz. Bir sonraki adım olarak, bu yapıyı hata yönetimi (error handling) süreçlerinize entegre etmeyi deneyebilirsiniz.

Ahmet Aksoy

Not: Bu yazıda incelediğimiz kodu ve benzer projelerin kaynak kodlarını https://github.com/ahmetax/practical-python-examples adresinde bulabilirsiniz.

python, python programlama, python öğren, yazılım, kod, yapısal pattern matching, match-case, veri ayrıştırma, orta seviye, python 3.10

Leave a Reply

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir