2.24. Bağlam yöneticileri¶
with ifadesi önce kurulum kodunu, sonra bir gövdeyi, ardından da yıkım kodunu çalıştırır – gövde yarıda başarısız olsa bile yıkımın çalışacağı garantisiyle. Kurulum ve yıkımı sağlayan yöntem çifti bağlam yöneticisi olarak adlandırılır.
Biçimi şöyledir:
with <expression> as <name>:
<body>
İfade bir bağlam yöneticisi döndürür. Python onun __enter__ yöntemini çağırır, isteğe bağlı olarak sonucu <name> öğesine bağlar, gövdeyi çalıştırır ve ardından – gövde normal olarak tamamlansa da bir istisna oluştursa da – __exit__ yöntemini çağırır.
__exit__, blok içinde ne olursa olsun bloğun sonunda çalışır.¶
2.24.1. Bir bağlam yöneticisi kullanmak¶
Tipik örnek, bir dosya açmaktır:
with open("data.txt") as f:
text = f.read()
# f is now closed, even if read() failed
open(), kendisi bir bağlam yöneticisi olan bir dosya nesnesi döndürür; __enter__ dosyayı döndürür ve __exit__ onu kapatır. with bloğu, “işin bitince dosyayı her zaman kapat” davranışını, çağıranın hatırlaması gereken bir şey olmaktan çıkarıp varsayılan hale getirir.
2.24.1.1. Birden fazla bağlam yöneticisi¶
Tek bir with ifadesi, virgüllerle ayrılmış olarak aynı anda birkaç bağlam yöneticisine girebilir:
with open("input.txt") as src, open("output.txt", "w") as dst:
dst.write(src.read())
İç içe iki with bloğuna eşdeğerdir ancak daha düzdür. Yöneticiler soldan sağa girilir ve ters sırayla çıkılır; sağdaki yöneticide __enter__ bir istisna oluşturursa, soldaki yöneticinin __exit__ yöntemi yine de çalışır.
2.24.2. Bir bağlam yöneticisi yazmak¶
__enter__ ve __exit__ yöntemlerine sahip herhangi bir sınıf bir bağlam yöneticisi olarak çalışır:
class Section:
def __init__(self, label):
self.label = label
def __enter__(self):
print("---", self.label, "---")
return self
def __exit__(self, exc_type, exc_value, traceback):
print("--- end", self.label, "---")
return False
with Section("setup"):
print("doing the work")
Çıktı:
--- setup ---
doing the work
--- end setup ---
__exit__, bloğu sonlandıran istisnayı tanımlayan üç argüman ya da blok normal olarak tamamlandıysa üç None değeri alır. False (veya None) döndürmek, yıkımdan sonra herhangi bir istisnanın yayılmasına izin verir; True döndürmek onu yutar.
Yalnızca dosyalar için değil, “aç / kapat” veya “edin / serbest bırak” yaşam döngüsüne sahip her kaynak için bağlam yöneticilerini kullanın. Bu kalıp, temizliği kurulumla, her ikisinin de tanıtıldığı noktada eşleştirir, böylece uzun bir fonksiyonun ortasında unutulan bir kapatma kaynağı sızdıramaz.