Python Context Managers

Kerem Vatandas
Dec 19, 2018 · 3 min read

Bu yazıda hangi konulara değineceğiz?

  • Context manager nedir?
  • With deyiminin kullanımı nasıldır?
  • Neden böyle bir yapıya ihtiyacımız var?
  • Decorator kullanımı kısa hatırlatma
  • Context manager oluşturmanın yolları nelerdir?

Python programlama dilinde kaynak kullanımı ve kaynakların geri iadesi için with deyimi bulunmaktadır. With deyimi bu işlemleri context management protocol’üne uygun olarak yapmaktadır. Yani bizde bu protokole uyarak kendi sınıflarımızı, kodumuzu yazabiliriz.

Python dilini kullanan herkes bir kere de olsa dosya işlemleri yapmış yada en azından okuduğu kodlarda bu yapıyı görmüştür. Genel yapı şöyledir.

# Dosya Aç
# Dosyaya Yaz yada Oku (Yada herhangi bir işlem yap)
# Dosyayı kapat

Context Manager Nedir?

  • Context manager kullanılan kaynakların geri iade edilmesi için ortaya çıkmış bir protokoldür. Bu protokolü kullanabilmemiz için belli kurallara uygun sınıflar, yapılar oluşturmamız gerekir.
  • Context manager protokolüne uygun yazdığımız sınıflarımızı kullanırken de with deyiminden yararlanacağız.

With Deyiminin Kullanımı

  • with deyiminin kullanımını ve bize getirdiği kolaylığı görmek için yukarıda bahsettiğimiz dosya işlemlerini hem with deyimini kullanarak hem de with deyimi olmadan nasıl yazabileceğimize birer örnek verelim.

İlk olarak with deyimini nasıl kullanıyoruz?

with <ifade> as degiskenIsmi:
<islemler>
with deyimi kullanımı

with deyimi olmasaydı bu işlemi güvenli bir şekilde nasıl yapabilirdik?

with deyimi olmadan dosya işlemleri
  • Kısaca açıklamak gerekirse temel yapılan hatalardan bir tanesi dosyayı açıp, işlemleri yaptıktan sonra dosyayı kapamayı unutmak büyük bir problem. Çünkü kullandığımız kaynaklar sınırsız değiller. Devamlı kaynak edinip geri iade etmessek işletim sisteminiz size engel olacaktır.
  • Ama bizim yazdığımız kodda finally bloğu her zaman çalışacaktır ve dosya kapama işlemini yapacaktır.
  • with kullanım alanı sadece dosya işlemleri değil elbette. Database bağlantıları, thread kullanım alanlarda lock mekanizmasında çokça kullanılıyor. Bu kısım oluşturmuş olduğunuz dizayna bağlıdır, yani genişletilebilir.

Kaynaklar sınırsız derken ne demek istiyorsunuz?

  • Hemen küçük bir kod ile açıklamaya çalışalım. Kodumuz şu şekilde çalışsın. 100_000 dosya açmaya çalışalım ve bu açtığımız dosyaları kapatmayalım. Bakalım neler olacak?

Kullandığınız işletim sistemine göre kaynak kullanımı değişiklik gösterecektir. Ben şu şekilde bir hata alıyorum. Hata da gördüğünüz gibi OSError

OSError: [Errno 24] Too many open files: 'files/4861'

Neden böyle bir yapıya ihtiyacımız var?

  • Bu hataları engellemek için kullandığımız kaynakları iade etmeliyiz. Bunun içinde pythonda context manager protokolü ve with deyimi var.

Context manager oluşturmanın yolları nelerdir?

  • with deyimi ve context manager protokolünün ne olduğunu, neden kullanmamız gerektiğini anladığımıza göre artık nasıl bu protokole uygun sınıflar yazabiliriz, onun üzerinde duralım.

Context manager oluşturmanın 2 yolu var.

  1. Class Kullanmak
  2. contexmanager decorator kullanmak

Context manager protokolüne uygun class oluşturma

Bir sınıfın context manager protokolüne uygun olabilmesi için __enter__ ve __exit__ metotlarını bulundurması gerekiyor.

  • __enter__ metodu self dışında herhangi bir parametre almaz
  • __exit__ metodu self dışında 3 parametre daha alıyor. (type, value, traceback)

Basit bir örnek yazalım ve nasıl çalıştığını anlayalım.

Context Manager Yapısını Anlama
init metodu calisti...
__enter__ metodu cagirildi...
with blogunun icindeyim...
__exit__ metodu cagirildi...

Çalışma akışını gördünüz. Sınıfımızı context manager protokolüne uygun şekilde yazdık ve daha sonra with deyimi ile birlikte kullandık.

  • Önce __init__ çalıştı.
  • İkinci olarak __enter__ metodu içinde ki işlem yapıldı ve işlem sonucu return ile geri dönüldü.
  • with deyimi <body> içerisindeki alan işlendi. Burada bir değişkene return edilen değeri atadık vb işlemler.
  • with bloğu bittiği gibi __exit__ metodu çağırıldı.

Artık çalışma yapısını da biliyoruz. Yukarıda ilk verdiğimiz dosya işlemleri üzerine bir örnek yazalım.

Context Manager Protokolüne Uygun Sınıf Tanımı
Dosya Kapatildi mi?[With Body] -> False
Dosya Kapatildi mi?[With blogu disi] -> True

Bu kadar örnek yeterli diye düşünüyorum. Şimdi ikinci bir yolumuz olan decorator yapısını kullanarak nasıl contextmanager protokolünü destekleyen kod yazabiliriz ona geçelim.


ContexManager Decorator Kullanımı

  • Diğer yöntem ise python dilinin sunduğu bir kütüphaneyi kullanmak. Bu kütüphanenin adı contextlib. Bu kütüphane içinde ki contextmanager decorator’ünü kullanacağız.

Kısaca decoratör yapısını hatırlayalım…

  • Decorator yapılar parametre olarak fonksiyon alıp geriye fonksiyon döndüren yapılardır. İki tür decorator yapısı var.
  1. class decorators
  2. function decorators
# Kullanımı@<fonkismi>(<varsa_parametreler>)
def func():
pass

Ufak bir hatırlatmadan sonra örneğimize geri dönelim.

contextmanager decorator yapısının kullanımı
Dosya Kapatildi mi?[With Body] -> False
Dosya Kapatildi mi?[With blogu disi] -> True

  • contextmanager decorator yapısının kodunu incelersek contextlib.py içerisinde ki _GeneratorContextManager isimli sınıfı kullandığını göreceğiz. Sınıf kodunu incelersek tıpkı bizim yazdığımız yapı gibi __init__ __enter__ ve __exit__ metotlarını göreceksiniz.

Bilişim Hareketi

Türkiye'nin bilişim alanında gelişmesi için bir katkı

Kerem Vatandas

Written by

#SoftwareEngineer

Bilişim Hareketi

Türkiye'nin bilişim alanında gelişmesi için bir katkı

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade