ayrıntıları biraz teknik olsun, bu yüzden basit sürümü ile başlayalım:
Bazı türleri bir with
açıklamada kullanılacak biliyorum. open
'dan geri aldığınız şeyler gibi dosya nesneleri, böyle bir örnektir. Sonuç olarak, urllib.request.urlopen
'dan geri döndüğünüz nesneler da türünde bir örnektir, böylece ikinci örneğiniz ilk ile aynı şekilde yazılabilir.
Bazı türler, bir with
deyiminde nasıl kullanılacağını bilmez.closing
işlevi, close
yöntemine sahip oldukları sürece, with
deyiminden çıktığınızda close
yöntemini çağırır. Onların temizleme yöntemi close
adında (ya da değil, çünkü bazı türleri de bir with
açıklamada kullanılacak bilen ve yok Tabii
closing
ile kullanılamaz onları temizlemeye sadece daha karmaşıktır çünkü onları kapatarak). Bu durumda, özel bir içerik yöneticisi yazmanız gerekir. Ama bu bile o kadar da zor değil. Teknik açıdan
:
A with
açıklamada bir context manager, __enter__
ve __exit__
yöntemlerle bir nesne gerektirir. __enter__
yöntemini çağırır ve as
deyiminde bu yöntem tarafından döndürülen değeri verir ve with
ifadesinin sonunda __exit__
yöntemini çağırır.
dosya nesneleri __exit__
aramalar self.close()
bir bağlam __enter__
yöntem, kendisi ile döner Yöneticisi ve bir io.IOBase
devralır.
urlopen
tarafından döndürülen nesne dokümanlar söylediği gibi, "Bir with
deyimi ile kullanılabilir", bir HTTPResponse
, (bir http
veya https
URL varsayarak) 'dir.
closing
fonksiyonu:
geri bloğunun tamamlanması üzerine bir şey kapatan bir bağlam yöneticisi. Bu temelde eşdeğerdir:
@contextmanager
def closing(thing):
try:
yield thing
finally:
thing.close()
It türleri bağlam yöneticileri ve türleri değildir dokümanlarında her zaman% 100 net. Özellikle 3.1'den beri büyük bir sürücü olduğu için, bir içerik yöneticisi haline getirilebilecek her şeyi (ve bu nedenle, çoğunlukla dosya-benzeri-gibi bir şeyleri gerçek bir IOBase
'a dönüştürmek) yapmak, ancak hala değil % 100'ü 3,4 olarak tamamlandı.
Her zaman deneyebilir ve görebilirsiniz. Bir AttributeError: __exit__
alırsanız, nesne bir içerik yöneticisi olarak kullanılamaz. Olması gerektiğini düşünüyorsanız, değişikliği öneren bir hata gönderin. Bu hatayı almazsanız, ancak dokümanlar yasal olduğunu belirtmezse, dokümanların güncellenmesini öneren bir hata oluşturur.
Birinin bunun için 'contextlib' üzerinde bir dosya hatası vermesi gerektiğini ve bunun için her kimsenin size kredi vermemesi gerektiğini söylemeyi düşünmek üzereydim ... ama bitiremeden önce, Martijn zaten bir hata yaptı buraya. :) – abarnert