-
Sadrazamv4
instagram:sadrazam.spy Tg:Sadrazamv4
================================================================================
🐍 SIFIRDAN İLERİ SEVİYEYE PYTHON EĞİTİM SERİSİ - BÖLÜM 4
================================================================================
Selamlar Değerli Forum Sakinleri! 🚀🔥
OOP, MRO algoritması ve Metasınıfların büyüleyici dünyasını geride bıraktık.
Şimdi fonksiyonel programlamanın bellek dostu mimarilerine ve Python'ın en
zarif yapılarına giriş yapıyoruz: **Bölüm 4!** ☕💻
Bu bölümde:
1. Closure (Kapanış) Mantığı ve `__closure__` Hücreleri
2. Decorator (Bezeyici) Mimarisi ve Wrappers
3. Iterators, Generators ve `yield` Protokolü (Lazy Evaluation)
--------------------------------------------------------------------------------
1. Fonksiyon İçi Bellek Koruması: Closure (Kapanış) 🔒
--------------------------------------------------------------------------------
Bir fonksiyon icra edildikten sonra yerel (local) değişkenleri bellekten
(stack) silinir. Ancak iç içe geçmiş fonksiyonlarda, içteki fonksiyon dıştaki
fonksiyonun değişkenini "hapsettiyse" buna **Closure** denir.
CPython bu durumu `cell` (hücre) adı verilen özel bellek alanlarında tutar.
Teorik Kod ve Bellek Hücresi İncelemesi:
def dis_us_al(taban):
# 'taban' değişkeni dis_us_al çalışması bitse bile silinmeyecek!
def ic_hesapla(us):
return taban ** us
return ic_hesapla
kare_al = dis_us_al(2)
kup_al = dis_us_al(3)
print(kare_al(4)) # 16 (2^4)
print(kup_al(3)) # 27 (3^3)
# Arka planda korunan hücre değerlerini doğrulama:
print(kare_al.__closure__[0].cell_contents) # Output: 2
print(kup_al.__closure__[0].cell_contents) # Output: 3
--------------------------------------------------------------------------------
2. Decorator (Bezeyici) Mimarisi ve Sintaktik Şeker 🍬
--------------------------------------------------------------------------------
Decorator'lar, var olan bir fonksiyonun davranışını kodunu değiştirmeden
genişletmeye yarayan Closure yapılardır. `@decorator_adi` kullanımı tamamen
bir "Syntactic Sugar" (Sintaktik Şeker) işlemidir.
Eşdeğer Mantık:
@loglayici
def topla(a, b): return a + b
# Yukarıdaki satır, arka planda BİREBİR şuna dönüşür:
# topla = loglayici(topla)
Teorik Süre Analiz Decorator'ı:
import time
from functools import wraps
def zaman_olc(func):
@wraps(func) # Fonksiyonun __name__ ve __doc__ metadata'sını korur
def wrapper(*args, **kwargs):
baslangic = time.perf_counter()
sonuc = func(*args, **kwargs)
bitis = time.perf_counter()
print(f"[LOG] {func.__name__} çalışma süresi: {(bitis - baslangic):.6f} sn")
return sonuc
return wrapper
@zaman_olc
def agir_islem():
return sum(i * i for i in range(1_000_000))
agir_islem()
--------------------------------------------------------------------------------
3. Generator, Iterator ve yield Protokolü ⚡
--------------------------------------------------------------------------------
Klasik listeler tüm veriyi RAM'e doldurur. Ancak milyarlarca veriden oluşan bir
süreçte bu durum `MemoryError` fırlatır.
Python burada **Lazy Evaluation (Tembel Değerlendirme)** ilkesini uygular:
"Veri istendiği an üretilsin, bellekte tutulmasın!"
A) Iterator Protokolü (`__iter__` ve `__next__`):
Bir nesnenin iterator olabilmesi için `__iter__()` (kendini döndüren) ve
`__next__()` (sonraki elemanı döndüren / bitince `StopIteration` fırlatan)
metotlarına sahip olması gerekir.
B) Generator ve `yield` İç Mimarisi:
Bir fonksiyonda `return` yerine `yield` kullanıldığında, fonksiyon çağrıldığında
çalışmaz; geriye bir Generator Nesnesi döndürür.
`yield` komutuna gelindiğinde CPython fonksiyonun durumunu (Local değişkenler,
Instruction Pointer) dondurur ve değeri dışarı fırlatır. Bir sonraki `next()`
çağrısında kaldığı yerden devam eder!
Bellek Farkı (List Comprehension vs Generator Expression):
import sys
# List Comprehension (Tüm 1 Milyon elemanı RAM'e basar)
liste = [x ** 2 for x in range(1_000_000)]
print(f"Liste RAM Kullanımı: {sys.getsizeof(liste)} bayt") # ~8 MB!
# Generator Expression (Sadece üretim kuralını tutar, veri RAM'de YOKTUR)
generator = (x ** 2 for x in range(1_000_000))
print(f"Generator RAM Kullanımı: {sys.getsizeof(generator)} bayt") # Sadece ~200 Bayt!
# Teker teker veriyi çekme:
print(next(generator)) # 0
print(next(generator)) # 1
print(next(generator)) # 4
--------------------------------------------------------------------------------
4. Bölüm Özeti ve Gelecek Adım 📌
--------------------------------------------------------------------------------
Bu bölümde Closure bellek hücrelerini, Decorator mimarisini ve devasa verileri
sıfır bellek tüketimiyle işleyen Generator/yield yapısını inceledik.
Devam etmek için forum başlığı altına "DEVAM" yazmanız yeterlidir!
Bir sonraki bölümde (Bölüm 5):
- Eşzamanlılık (Concurrency) ve Paralellik (Parallelism)
- GIL (Global Interpreter Lock) Nedir, Neden Var, Nasıl Bypassed Edilir?
- `threading`, `multiprocessing` ve `asyncio` Derin İncelemesi
Sorularınızı ve teorik katk
ılarınızı aşağıda bekliyorum! 🚀✨
================================================================================
🐍 SIFIRDAN İLERİ SEVİYEYE PYTHON EĞİTİM SERİSİ - BÖLÜM 4
================================================================================
Selamlar Değerli Forum Sakinleri! 🚀🔥
OOP, MRO algoritması ve Metasınıfların büyüleyici dünyasını geride bıraktık.
Şimdi fonksiyonel programlamanın bellek dostu mimarilerine ve Python'ın en
zarif yapılarına giriş yapıyoruz: **Bölüm 4!** ☕💻
Bu bölümde:
1. Closure (Kapanış) Mantığı ve `__closure__` Hücreleri
2. Decorator (Bezeyici) Mimarisi ve Wrappers
3. Iterators, Generators ve `yield` Protokolü (Lazy Evaluation)
--------------------------------------------------------------------------------
1. Fonksiyon İçi Bellek Koruması: Closure (Kapanış) 🔒
--------------------------------------------------------------------------------
Bir fonksiyon icra edildikten sonra yerel (local) değişkenleri bellekten
(stack) silinir. Ancak iç içe geçmiş fonksiyonlarda, içteki fonksiyon dıştaki
fonksiyonun değişkenini "hapsettiyse" buna **Closure** denir.
CPython bu durumu `cell` (hücre) adı verilen özel bellek alanlarında tutar.
Teorik Kod ve Bellek Hücresi İncelemesi:
def dis_us_al(taban):
# 'taban' değişkeni dis_us_al çalışması bitse bile silinmeyecek!
def ic_hesapla(us):
return taban ** us
return ic_hesapla
kare_al = dis_us_al(2)
kup_al = dis_us_al(3)
print(kare_al(4)) # 16 (2^4)
print(kup_al(3)) # 27 (3^3)
# Arka planda korunan hücre değerlerini doğrulama:
print(kare_al.__closure__[0].cell_contents) # Output: 2
print(kup_al.__closure__[0].cell_contents) # Output: 3
--------------------------------------------------------------------------------
2. Decorator (Bezeyici) Mimarisi ve Sintaktik Şeker 🍬
--------------------------------------------------------------------------------
Decorator'lar, var olan bir fonksiyonun davranışını kodunu değiştirmeden
genişletmeye yarayan Closure yapılardır. `@decorator_adi` kullanımı tamamen
bir "Syntactic Sugar" (Sintaktik Şeker) işlemidir.
Eşdeğer Mantık:
@loglayici
def topla(a, b): return a + b
# Yukarıdaki satır, arka planda BİREBİR şuna dönüşür:
# topla = loglayici(topla)
Teorik Süre Analiz Decorator'ı:
import time
from functools import wraps
def zaman_olc(func):
@wraps(func) # Fonksiyonun __name__ ve __doc__ metadata'sını korur
def wrapper(*args, **kwargs):
baslangic = time.perf_counter()
sonuc = func(*args, **kwargs)
bitis = time.perf_counter()
print(f"[LOG] {func.__name__} çalışma süresi: {(bitis - baslangic):.6f} sn")
return sonuc
return wrapper
@zaman_olc
def agir_islem():
return sum(i * i for i in range(1_000_000))
agir_islem()
--------------------------------------------------------------------------------
3. Generator, Iterator ve yield Protokolü ⚡
--------------------------------------------------------------------------------
Klasik listeler tüm veriyi RAM'e doldurur. Ancak milyarlarca veriden oluşan bir
süreçte bu durum `MemoryError` fırlatır.
Python burada **Lazy Evaluation (Tembel Değerlendirme)** ilkesini uygular:
"Veri istendiği an üretilsin, bellekte tutulmasın!"
A) Iterator Protokolü (`__iter__` ve `__next__`):
Bir nesnenin iterator olabilmesi için `__iter__()` (kendini döndüren) ve
`__next__()` (sonraki elemanı döndüren / bitince `StopIteration` fırlatan)
metotlarına sahip olması gerekir.
B) Generator ve `yield` İç Mimarisi:
Bir fonksiyonda `return` yerine `yield` kullanıldığında, fonksiyon çağrıldığında
çalışmaz; geriye bir Generator Nesnesi döndürür.
`yield` komutuna gelindiğinde CPython fonksiyonun durumunu (Local değişkenler,
Instruction Pointer) dondurur ve değeri dışarı fırlatır. Bir sonraki `next()`
çağrısında kaldığı yerden devam eder!
Bellek Farkı (List Comprehension vs Generator Expression):
import sys
# List Comprehension (Tüm 1 Milyon elemanı RAM'e basar)
liste = [x ** 2 for x in range(1_000_000)]
print(f"Liste RAM Kullanımı: {sys.getsizeof(liste)} bayt") # ~8 MB!
# Generator Expression (Sadece üretim kuralını tutar, veri RAM'de YOKTUR)
generator = (x ** 2 for x in range(1_000_000))
print(f"Generator RAM Kullanımı: {sys.getsizeof(generator)} bayt") # Sadece ~200 Bayt!
# Teker teker veriyi çekme:
print(next(generator)) # 0
print(next(generator)) # 1
print(next(generator)) # 4
--------------------------------------------------------------------------------
4. Bölüm Özeti ve Gelecek Adım 📌
--------------------------------------------------------------------------------
Bu bölümde Closure bellek hücrelerini, Decorator mimarisini ve devasa verileri
sıfır bellek tüketimiyle işleyen Generator/yield yapısını inceledik.
Devam etmek için forum başlığı altına "DEVAM" yazmanız yeterlidir!
Bir sonraki bölümde (Bölüm 5):
- Eşzamanlılık (Concurrency) ve Paralellik (Parallelism)
- GIL (Global Interpreter Lock) Nedir, Neden Var, Nasıl Bypassed Edilir?
- `threading`, `multiprocessing` ve `asyncio` Derin İncelemesi
Sorularınızı ve teorik katk
ılarınızı aşağıda bekliyorum! 🚀✨
================================================================================
🔒 Bu içeriği görmek için giriş yapın