Son gün! Python’un ileri seviye özelliklerini keşfedeceğiz. Bu konular, dili tam anlamıyla kavramanızı ve daha profesyonel yazılım geliştirmenizi sağlayacak.
1. Iteratorlar ve Generatorlar
Iterator Nedir?
Iterator, üzerinde dolaşılabilen (iterable) nesneleri sırasıyla döndüren bir yapıdır. Listeler, demetler gibi veri yapıları iterator olarak kullanılabilir.
numbers = [1, 2, 3, 4]
iterator = iter(numbers)
print(next(iterator)) # 1
print(next(iterator)) # 2
Generator Nedir?
Generator, iterator’ların özel bir türüdür ve yield ifadesi ile
tanımlanır. Memory dostudur — tüm veriyi aynı anda bellekte tutmaz,
gerektiğinde üretir.
def sayi_generator():
for i in range(5):
yield i
for sayi in sayi_generator():
print(sayi)
Bu kodda yield ifadesi sayesinde her bir sayı ihtiyaç duyuldukça
üretilir. Büyük veri setlerinde RAM tasarrufu sağlar.
2. Context Managers ve with
Context Manager, bir dosya veya kaynak işlemi sonrasında temizlemeyi
garanti eder. with ifadesi bunu sağlar:
with open("dosya.txt", "w") as dosya:
dosya.write("Merhaba, dünya!")
# Burada dosya otomatik kapanır — hata olsa bile
Olası kaynak sızıntıları önlenmiş olur. Dosya, veritabanı bağlantısı, ağ socket’leri gibi her kaynak için ideal.
3. Dekoratörler
Dekoratörler, Python’da fonksiyonları dinamik olarak değiştirmek için kullanılan yapılardır. Fonksiyonlara yeni davranışlar kazandırır.
Fonksiyon Dekoratörü
def dekorator(fonksiyon):
def sarmalici(*args, **kwargs):
print("Fonksiyon başlamadan önce")
sonuc = fonksiyon(*args, **kwargs)
print("Fonksiyon tamamlandı")
return sonuc
return sarmalici
@dekorator
def selamla():
print("Merhaba!")
selamla()
# Çıktı:
# Fonksiyon başlamadan önce
# Merhaba!
# Fonksiyon tamamlandı
@dekorator ile fonksiyonun çalışma şekli değiştirildi — kaynak kodu
tek bir satır ile genişletildi.
Pratik Dekoratör Örnekleri
@staticmethod,@classmethod— sınıf metodları@property— özelliklere getter/setter@lru_cache— fonksiyon sonuçlarını cache’lemek- Yetkilendirme dekoratörleri (web framework’lerinde)
4. İleri Seviye Hata Yönetimi
Önceki günlerde temel hata yönetimine değindik. Şimdi özel hata sınıflarıyla sistematik bir yapı kuralım:
class OzellestirilmisHata(Exception):
"""Özel iş kuralları ihlallerinde fırlatılır."""
pass
def hata_firlatici():
raise OzellestirilmisHata("Bu bir özel hatadır.")
try:
hata_firlatici()
except OzellestirilmisHata as e:
print(f"Hata yakalandı: {e}")
Bir projede iş alanına özgü hatalar tanımlayarak, hata yönetimi mantığını netleştirebilir ve dokümante edebilirsiniz.
5. İleri Seviye Veri Yapıları
Queue (Kuyruk) — FIFO
FIFO (First In, First Out) mantığıyla çalışır.
from collections import deque
kuyruk = deque()
kuyruk.append("A")
kuyruk.append("B")
print(kuyruk.popleft()) # A
print(kuyruk.popleft()) # B
Stack (Yığın) — LIFO
LIFO (Last In, First Out) mantığıyla çalışır.
yigin = []
yigin.append(10)
yigin.append(20)
print(yigin.pop()) # 20
print(yigin.pop()) # 10
Deque (Double-ended Queue)
Her iki uçtan ekleme/çıkarma yapılabilen yapıdır. collections.deque
hem stack hem queue olarak kullanılabilir, O(1) performansla.
6. Metaclass
Metaclass, Python’da sınıfların nasıl tanımlandığını ve nasıl davranacağını kontrol eder. Sınıf yapısına düşük seviyede müdahale imkânı verir.
class MyMeta(type):
def __new__(cls, name, bases, attrs):
print(f"Yeni bir sınıf oluşturuluyor: {name}")
return super().__new__(cls, name, bases, attrs)
class MyClass(metaclass=MyMeta):
pass
# Çıktı: Yeni bir sınıf oluşturuluyor: MyClass
Ne zaman kullanılır? Genelde framework geliştirenler kullanır (Django ORM, SQLAlchemy gibi). Günlük kodda nadiren ihtiyaç olur ama ileri Python ekosistemini anlamak için bilmek önemli.
7. Mini Proje: Dosya Okuma Iterator’u
Şimdi öğrendiklerimizi birleştiren küçük bir proje yapalım. Bir dizindeki tüm dosyaları okuyup içeriğini sırayla döndüren bir custom iterator:
import os
class DosyaIterator:
def __init__(self, klasor_yolu):
self.klasor_yolu = klasor_yolu
self.dosyalar = iter(os.listdir(klasor_yolu))
def __iter__(self):
return self
def __next__(self):
dosya_adi = next(self.dosyalar)
tam_yol = os.path.join(self.klasor_yolu, dosya_adi)
with open(tam_yol, 'r') as f:
return f.read()
# Kullanım
dosya_iteratoru = DosyaIterator("/path/to/klasor")
for dosya_icerik in dosya_iteratoru:
print(dosya_icerik)
Bu iterator, verilen klasördeki her dosyayı sırayla açıp içeriğini
döndürür. __iter__ ve __next__ metodlarını uygulayarak Python’un
iterator protokolüne dahil olduk.
🎉 Tebrikler!
5 günlük Python BootCamp’ini başarıyla tamamladın!
Bu 5 günlük yolculukta, Python’un temellerinden başlayarak ileri düzey konulara kadar geniş bir yelpazede bilgi sahibi oldun. Her gün bir adım daha derinleştik. Artık:
- Temel sözdiziminden ileri seviye OOP’a kadar her şeyi biliyorsun
- Asenkron programlama ve paralel işleme üzerinde çalışabilirsin
- Veritabanı, API ve web scraping ile veri akışı kurabilirsin
- Pandas ile veri analizi yapabilirsin
- Iterator, generator, decorator ve metaclass gibi ileri yapıların ne işe yaradığını biliyorsun
Sonraki Adımlar
- FastAPI / Django ile web backend geliştirme
- NumPy / scikit-learn ile veri bilimi ve makine öğrenmesi
- PyQt / Tkinter ile masaüstü uygulama geliştirme
- Async libraries (
aiohttp,httpx) ile yüksek performanslı I/O - Real proje: öğrendiklerini birleştiren bir araç yazmak (örn. CLI ile çalışan bir web scraper + veritabanı + raporlama)
Python öğrenme yolculuğu burada bitmiyor — devamı senin elinde. 🐍