2013-08-12 35 views
5

Ben Python ile bir noob değilim, ama böyle bir otomatik kapanma fonksiyonu yazdım ..Otomatik kapanma sınıfı yazmanın Pythonic yolu nedir?

@contextmanager 
def AutoClose(obj): 
    try: 
     yield obj 
    finally: 
     obj.Close() 

Bu fonksiyon ile kullanılabilen bir Kapat() yöntemine sahip üç sınıf vardır. Bu en çok Pythonic çözümü mi? Bunun yerine sınıflarda bir şeyler yapmalı mıyım?

+0

Bu iyi görünüyor. Sınıfınızda bir yok edici de kullanabilirsiniz. – akiniwa

+1

Yıkıcıyı kullanmaktan kaçınıyorum (örn. __del__'). Ne zaman çağrılırsa akılda tutulması gerçekten zor. Burada kabul edilen cevaba bakınız: http://stackoverflow.com/questions/1935153/del-method-being-called-in-python-when-it-is-not-expected – tom

cevap

8

Yaptığınız şey gayet iyi ve Pythonic. Bununla birlikte, contextlib standart kitaplığı zaten benzer bir şeye sahip olsa da, Close yöntemlerinizi close olarak yeniden adlandırmanız gerekir.

import contextlib 
with contextlib.closing(thing): 
    print thing 

Bunun yerine bunu kullanmanızı öneririm. Sonuçta, Python yöntemleri için önerilen adlandırma kuralı all_lowercase_with_underscores'dur.

class Foo(object): 
    def __init__(self, filename): 
     self.filename = filename 

    def __enter__(self): 
     self.fd = open(self.filename) 

    def __exit__(self, exc_type, exc_value, traceback): 
     self.fd.close() 

Ve kullanarak: girerek ve bloklar with ayrılırken

with Foo('/path/to/file') as foo: 
    # do something with foo 

Yöntemleri __enter__ ve __exit__ örtük adı verilecek

+0

'Bluedog' da yeniden adlandırmak zorunda kalabilir. onun (veya onun) .Close() yönteminin, contextlib.closing() işlevini kullanmak için .close() yöntemine (yanılmıyorsa). –

+0

Geçerli durumla Close() yöntemini korumalıyım, ancak standart contextlib.closing işlevinin kullanılabilmesi için close() adında bir ad ekleyebilirim. – bluedog

9

En pythonic çözüm yöntemleri sınıfınızda __enter__ and __exit__ yöntemleri tanımlamaktır. Ayrıca __exit__'un, with bloğunun içinde yükselen istisnayı yakalamanıza izin verdiğini de unutmayın.

Fonksiyon contextlib.closing tipik olarak açık bir yöntem __enter__ ve __exit__ tanımlar (ancak bir yöntem close var) olmayan bu sınıflar için kullanılır. Kendi sınıflarınızı tanımlarsanız, bu yöntemleri tanımlamanın daha iyi bir yolu vardır.

+0

+1 - Bu eşit derecede iyi bir yanıt IMO. @tom s cevabını seçtim çünkü bu vesileyle kullanacağım çözüm. Üç özel sınıfın tümü bir Close() yöntemine sahiptir ve \ _ \ _ enter \ _ \ _ için herhangi bir gereksinime sahip değildir, böylece tek auto_close işlevi, sınıfların kendilerine dokunmadan üç sınıf için kullanılabilir. – bluedog

İlgili konular