Python Generator Kavramı

Generators

Python Generator Kavramı

  • Kullanım Senaryosu:

    • Bir fonksiyon çok yüksek miktarda veri dönüyorsa ve memory gereksiz yere şişirilmek istenmiyorsa (aşırı yükten sisteminiz crash olabilir, diğer process'leriniz olumsuz etkilenebilir.) generator fonksiyon oldukça faydalı olacaktır.
  • Generator fonksiyonlar bir iterator gibi davranan fonksiyonlar tanımlamamıza olanak sağlar.

  • Python'ın iterator protokolünü implement eder.

  • PEP 255 'te tanıtılmıştır.

  • Bir list için nasıl loop ile içerisindeki veriye erişebiliyorsak, generator'ların ürettiği veriye de loop ile erişebiliriz.

  • Bir generator oluşturabilmek için yield keyword'unu ya da comprehension'ları kullanıyoruz.

  • yield keyword'u sadece fonksiyonların içerisinde kullanılabilir.

  • yield keyword'u normal bir fonksiyonu generator fonksiyonuna dönüştürür.

  • Generator tanımlamak için ve muhafaza ettiği veriye erişebilmek için aşağıdaki örnekleri inceleyelim

  • for loop ile de generator'ların ürettği veriye erişebilmekteyiz

  •  

yield vs return

  • return statement fonksiyondaki değeri verdikten sonra fonksiyonu sonlandırır.

  • yield statement'a geldiğimizde programımız çalışmayı duraklatır(pause veya suspend) ve yield değerini çağırılan yere döndürür(verir).

    • Bir fonksiyon duraksamaya geçtiğinde(pause veya suspend), fonksiyonun state'i(değişkenler, instruction pointer, internal stack, exception vs. de dahil) kaydedilir.

Gerçek Dünyadan Örnek

  • En yaygın senaryolardan birisi yüksek boyutlu dosya okuma işlemidir.

  • read_file.py

  • read_file_yield.py

  • İki aded dosyayı çalıştırıp sonuçlarını görelim. Dosyaların boyutları aşağıdaki gibidir

Dosya boyutureturnyield
1.5 MBMemory: 17.508 MB, Time: 0.04sMemory: 9.384 MB, Time: 0.03 s
7.1 MBMemory: 54.887 MB, Time: 0.08sMemory: 9.536 MB, Time: 0.11s
  • yield statement returne göre biraz yavaş çünkü generator fonksiyonunun state'inin izlenmesi(track) gerekiyor.
  • Ancak memory kullanımı yield statement'ta return statement'a göre oldukça performanslı.

Generator'lara veri göndermek

send fonksiyonu ile generator'lara veri gönderebiliriz. Aşağıdaki yapıyı inceleyelim

 

yield from expression

  • Generatorları chain etmek için ve iterable'ları birlikte kullanmaya olanak verir.

  • verilen expression dan sub-iterator oluşturmayı sağlar. sub-iterator tarafından üretilen bütün değerler çağrılan yere pass edilir.

  •  

Kaynaklar

 

Yorumlar