Python tip ipuçları: söz dizimi, mypy ve kademeli geçiş
Beceri rehberi

Python tip ipuçları: söz dizimi, mypy ve kademeli geçiş

Hazırlayan: Mindset Institute EditörlüğüGüncellendi: 6 dk okuma

Python tip ipuçlarını yazmayı, mypy ile denetlemeyi ve eski koda kademeli eklemeyi örneklerle öğrenin; Optional, Callable ve Protocol kullanımını görün.

Tip ipuçları ne işe yarar, ne işe yaramaz?

Python dinamik tiplidir: bir değişken önce metin, sonra sayı taşıyabilir ve bunu dil engellemez. Tip ipuçları (type hints) bu esnekliği bozmadan koda, "bu parametre metin bekler, bu fonksiyon sayı döndürür" bilgisini ekler. Önemli ayrıntı şudur: typing belgesinin de belirttiği gibi ipuçları çalışma anında zorlanmaz. Yanlış türde argümanla fonksiyonu çağırırsanız program yine çalışır; hatayı ancak ipuçlarını okuyan bir araç, yani bir tip denetleyicisi yakalar.

Bu yüzden tip ipuçlarının somut faydaları vardır. İlki okunabilirlik: fonksiyon imzası, belgeye bakmadan ne beklediğini söyler. Sonra editör desteği: tamamlama ve gezinme, tipi bilinen nesnelerde belirgin biçimde iyileşir. Son olarak erken hata yakalama: mypy gibi araçlar kodu çalıştırmadan, tür uyumsuzluklarını ve None üzerinde yapılan yanlış işlemleri raporlar.

Temel söz dizimi: parametre, dönüş ve koleksiyon tipleri

Parametre tipi iki nokta ile, dönüş tipi ok işaretiyle yazılır:

def indirim_uygula(fiyat: float, oran: float) -> float: return fiyat - fiyat * oran

def kullanici_adi(kimlik: str) -> str | None: ...

İçerik tipi belli koleksiyonlar için yerleşik türlerin kendisi kullanılır: list[str], dict[str, float], tuple[str, ...] gibi. Belgeye göre tuple'da konum başına tip verebilir, tuple[int, ...] ile her uzunlukta int demeti anlatabilirsiniz. Eski kodlarda typing modülünden List ve Dict importunu görürsünüz; güncel kodda gerek yoktur.

Birden çok tip kabul eden alanlar için X | Y yazımı önerilir (eşdeğeri Union). Optional[X] ise X ya da None demektir; bunu varsayılan değeri olan argümanla karıştırmayın. def f(a: int = varsayilan) argümanı isteğe bağlı yapar ama tipi Optional yapmaz; None kabul etmek istiyorsanız int | None yazarsınız.

Değişkenlere de tip verilebilir: toplam: float = deger. Çoğu zaman gerekmez, çünkü denetleyici atamadan tipi çıkarır; boş bir liste gibi tipi çıkarılamayan yerlerde (kalemler: list[str] = []) yardımcı olur.

mypy'ı kurun ve ilk hatayı yakalayın

mypy, tip ipuçlarını okuyan ve kodu çalıştırmadan denetleyen statik bir araçtır. Kurulum pip ile yapılır, çalıştırma ise dosya adı vermekle olur:

pip install mypy mypy program.py

Belgedeki klasik örnek şudur:

def greeting(name: str) -> str: return "Hello " + name

greeting(arguman)

arguman bir tamsayı ise mypy, ilk argümanın uyumsuz tipte olduğunu raporlar: tamsayı verilmiş, metin bekleniyor. Mesajda satır numarası, hata açıklaması ve beklenen tür görünür. Kodu çalıştırmadan bulunan bu hata, üretimde TypeError'a dönüşmeden önce yakalanmış demektir.

Kullanışlı bir alışkanlık, bir ifadenin denetleyici tarafından hangi tür sayıldığını görmek için reveal_type kullanmaktır: mypy bu çağrıyı gördüğünde çıkarım yaptığı tipi mesaj olarak yazar. Beklentinizle çıkarım ayrışıyorsa, ipucu eksik ya da yanlış demektir.

mypy komut satırı bayraklarıyla kontrol edilir; kalıcı ayarlar için proje kökünde bir yapılandırma dosyası kullanılır. Ekip içinde herkesin aynı sonucu görmesi için ayarların komut satırında değil dosyada durması doğru olandır.

Kademeli tiplendirme: eski koda nasıl eklenir?

mypy kademeli tiplendirmeyi (gradual typing) destekler. Belgeye göre ipucu içermeyen fonksiyonlar dinamik tipli sayılır ve varsayılan olarak atlanır. Yani bir kod tabanına istediğiniz kadarını yazarak başlayabilirsiniz. Sürecin sırası şöyle olabilir:

  • Önce mypy'ı hata verecek ayarlarda değil, rapor edecek şekilde çalıştırın ve mevcut durumu kaydedin.
  • Halka açık sınırlardan başlayın: modüller arasında paylaşılan fonksiyonların parametre ve dönüş tipleri, veri modelleri.
  • --check-untyped-defs bayrağıyla ipucu içermeyen fonksiyonların gövdesini de denetletin; bu bayrak bazı hataları ipucu yazmadan yakalar.
  • --disallow-untyped-defs ile yeni yazılan fonksiyonlarda ipucunu zorunlu kılın. Eski modülleri yapılandırma dosyasında tek tek muaf tutarak ilerleyin.
  • Hazır olduğunuzda --strict bayrağını açın. Belge, bu bayrağın büyük mevcut kod tabanları için fazla agresif olabileceğini, ama bununla başlayıp tek tek kontrolleri kapatmanın mümkün olduğunu söyler.
  • Tip bilgisi sunmayan üçüncü taraf kütüphaneler için --ignore-missing-imports yardımcı olur; ama bunu geçici çözüm olarak görün.

Son adım, mypy'ı sürekli entegrasyona eklemektir. Ekipçe yalnızca yeni uyarıların kabul edilmediği bir kapı kurmak, tipli kod oranını zamanla kendiliğinden artırır.

Callable, TypeVar, Protocol ve Any: ileri araçlar

Fonksiyon alan fonksiyonlar için Callable kullanılır: Callable[[int, str], bool], int ve str alan, bool döndüren bir fonksiyondur. Parametre listesi önemsizse Ellipsis yazılır. Callable, collections.abc modülünden içe aktarılır.

Girdi tipine bağlı bir çıktı tipi anlatmak için tip değişkeni (TypeVar ya da güncel söz diziminde köşeli parantezli genel tip) gerekir. Belgedeki örnek, bir dizinin ilk elemanını döndüren fonksiyondur: giriş int listesiyse dönüş int, metin listesiyse dönüş metin olur. İsterseniz tip değişkenini sınırlayabilirsiniz.

Protocol, yapısal alt tipleme sağlar. Belgenin örneğinde close metodu olan her nesne, Closable protokolüne uyar; sınıfın protokolden türemesi gerekmez. Bu, ördek tipleme ile statik denetimi birleştirir ve kompozisyonla kurulan kodda özellikle işe yarar.

Any, denetleyiciyi susturan kaçış kapısıdır: Any tipli bir değerle her işlem serbesttir ve her tipe atanabilir. Tipini bilmediğiniz ama güvenle ele aldığınız değerler için object daha güvenlidir, çünkü denetleyici object üzerinde çoğu işlemi reddeder. Pratikte Any yayılır: bir fonksiyon Any döndürürse onu kullanan her ifade denetimsiz kalır. Any'yi sınırlarda ve geçici olarak kullanın.

Sık hatalar ve kaçınma yolları

  • Çalışma anında kontrol sanmak: ipuçları programı korumaz; dışarıdan gelen veriyi ayrıca doğrulamak gerekir. Bunun için Pydantic gibi doğrulama kütüphaneleri vardır.
  • Optional ile varsayılan değeri karıştırmak: isteğe bağlı argüman başka şeydir, None kabul eden tip başka.
  • Her yere Any yazmak: sorun görünmez olur, ama mypy yeşil kalır. Any sayısını izleyin.
  • type: ignore yorumlarını biriktirmek: her biri gizlenmiş bir hatadır. Bırakıyorsanız yanına neden yazın.
  • list[int] değerini list[float] bekleyen yere vermek: listeler içerik tipinde değişmezdir (invariant), bu yüzden mypy bunu reddeder. Salt okunur kullanım için Sequence gibi soyut tipleri tercih edin.
  • Çıkarımı yok saymak: mypy çoğu yerel değişkenin tipini kendisi bulur; her değişkene elle ipucu yazmak gürültü yaratır.
  • mypy'ı yalnız yerelde çalıştırmak: sürekli entegrasyonda koşmayan denetim, zamanla bozulur.

Her ipucu, kodu okuyacak kişi için yazılmış bir sözleşmedir. İpucu yazarken sorulacak soru, "mypy ne diyecek"ten çok "bu imza, fonksiyonun gerçek davranışını doğru anlatıyor mu" olmalıdır.

Tipli Python yazmayı nerede çalışırsınız?

Mindset'in Python ile Nesne Yönelimli Programlama eğitiminde Veri Sınıfları, Tipler ve Doğrulama başlıklı bir modül ile Metaclass, Kalite ve Refaktör başlıklı bir modül yer alır. İpuçlarını veri modeli ve sınıf tasarımıyla birlikte öğrenmek, tipin neden arayüz sözleşmesinin parçası olduğunu somutlaştırır.

Bu içerik, tipsiz büyümüş bir kod tabanını sağlamlaştırmak isteyen, kod incelemelerinde 'bu parametre ne bekliyor' sorusuyla sık karşılaşan Python ekipleri için uygundur. Kurumsal ekipler tip denetimini sürekli entegrasyon kapısına bağlayarak ortak bir kalite ölçütü oluşturabilir.

İlgili Mindset programı

Python ile Nesne Yönelimli Programlama

Sık sorulanlar

Sık sorulan sorular

Tip ipuçları programı yavaşlatır mı?

Genel olarak hayır. İpuçları yorumlayıcı tarafından saklanır ama işlemler sırasında zorlanmaz; fonksiyon çağrıları aynı hızda çalışır. Küçük bir ek yük yalnızca modül içe aktarılırken ipuçlarının değerlendirilmesiyle oluşur. Denetim maliyeti mypy çalıştırdığınızda, yani geliştirme ve CI sırasında ortaya çıkar.

Her fonksiyona tip yazmak zorunda mıyım?

Hayır. mypy kademeli tiplendirmeyi destekler ve ipucu içermeyen fonksiyonları varsayılan olarak atlar. Yine de modüller arası paylaşılan fonksiyonlarda ve veri modellerinde ipucu yazmak en yüksek faydayı sağlar. Ekip kuralı olarak yeni kodda zorunlu kılıp eski koda zamanla yayılmak gerçekçi bir yoldur.

mypy ile editörün tip denetimi aynı şey mi?

Aynı ipuçlarını okurlar ama aynı aracı çalıştırmak zorunda değiller. Birçok editör kendi gömülü denetleyicisini kullanır; sonuçlar küçük farklarla ayrışabilir. Ekipte tek referans olarak sürekli entegrasyonda çalışan denetleyiciyi seçin ve ayarlarını yapılandırma dosyasında sabitleyin.

Tip denetimi test yazmanın yerini tutar mı?

Hayır, tamamlayıcıdır. Denetleyici tür uyumsuzluklarını ve None hatalarını yakalar ama iş mantığının doğruluğunu bilmez. Bir fonksiyon doğru tipte yanlış sonuç da döndürebilir. İkisini birlikte kullanmak, hem yapısal hataları hem davranış hatalarını kapsar.

Python'da tip ipuçlarını çalışma anında kullanabilir miyim?

Kendiniz okuyabilirsiniz, çünkü ipuçları fonksiyon ve sınıf üzerinde saklanır; Pydantic gibi kütüphaneler tam da bunu yaparak girdiyi doğrular. Standart Python ise bu bilgiyi kullanarak değer kontrolü yapmaz. Zorlayıcı doğrulama istiyorsanız ilgili kütüphaneyi ekleyin.

Python Type Hints ve mypy Nasıl Kullanılır?