Python’da “With” İfadesi

With ifadesi Python üzerinde bir blok içerisindeki kodları iki metot arasına almamızı sağlar. Klasik bir örnek olarak;

with open('metin.txt', 'w') as f:
    f.write('Lorem ipsum')

Burada blok içinde kodumuz çalışmadan önce ve sonra çalışan dosya açma ve kapama olmak üzere iki fonksiyonumuz vardır.

With üzerinde kullanabilmek için kendimiz de sınıflar oluşturabiliriz. Kullanılacak sınıf içerisinde __enter__ ve __exit__ metotları bulunmalı. Aşağıdaki Ornek sınıfımız with ile kullanıldığında ona verilen Sayi sınıfından bir örneğin değerini, blok çalışmadan önce ve sonra konsola yazar.

class Ornek():
    def __init__(self, sayi):
        self.sayi = sayi
        
    def __enter__(self):
        print("İşleme başlanan sayi ", str(self.sayi.deger))
        return self.sayi
    
    def __exit__(self, type, value, traceback):
        print("Sayının son değeri ", str(self.sayi.deger))


class Sayi:
    def __init__(self, deger):
        self.deger = deger
    
    def arttir(self):
        self.deger += 10

sayi = Sayi(5)
with Ornek(sayi):
    sayi.arttir()

#İşleme başlanan sayı  5
#Sayının son değeri  15

# diğer bir kullanım da şu şekilde olabilir.
with Ornek(Sayi(3)) as sayi:
    sayi.arttir()
#İşleme başlanan sayı  3
#Sayının son değeri  13

Peki with bloğumuz bitmeden bir hata oluşursa ne olur? With ifadesi burada oluşan exception’u yakalar ve exit metodunu uygun parametrelerle çağırır. Yani exit durumda çağrılan bir fonksiyon fakat burada bir hata olup olmadığı kontrolü yapmak yazılımcıya kalmış bir durum.

With üzerinde kullanmak için sınıf yerine bir Generator Fonksiyon‘da kullanabiliriz. Pytohn üzerinde bulunan contextlib modülünden contextmanager dekoratörü ile bir generator fonksiyonu with üzerinde kullanıma uygun hale getirebiliriz. Satır sayısı olarak daha az gibi gözükse de sınıf kullanmak daha anlaşılır olacaktır.

from contextlib import contextmanager

@contextmanager
def Ornek(sayi):
    print("İşleme başlanan sayi ", str(sayi.deger))
    yield sayi
    print("Sayının son değeri ", str(sayi.deger))

Bir Cevap Yazın