Eu recomendo usar a with
declaração do Python para gerenciar recursos que precisam ser limpos. O problema com o uso de uma close()
declaração explícita é que você precisa se preocupar com as pessoas que se esquecem de chamá-la ou se esquecem de colocá-la em um finally
bloco para evitar que um recurso vaze quando ocorrer uma exceção.
Para usar a with
instrução, crie uma classe com os seguintes métodos:
def __enter__(self)
def __exit__(self, exc_type, exc_value, traceback)
No seu exemplo acima, você usaria
class Package:
def __init__(self):
self.files = []
def __enter__(self):
return self
# ...
def __exit__(self, exc_type, exc_value, traceback):
for file in self.files:
os.unlink(file)
Então, quando alguém quisesse usar sua classe, faria o seguinte:
with Package() as package_obj:
# use package_obj
A variável package_obj será uma instância do tipo Package (é o valor retornado pelo __enter__
método). Seu __exit__
método será chamado automaticamente, independentemente de ocorrer ou não uma exceção.
Você pode até levar essa abordagem um passo adiante. No exemplo acima, alguém ainda pode instanciar o Package usando seu construtor sem usar a with
cláusula Você não quer que isso aconteça. Você pode corrigir isso criando uma classe PackageResource que define o __enter__
e __exit__
métodos. Em seguida, a classe Package seria definida estritamente dentro do __enter__
método e retornada. Dessa forma, o chamador nunca poderia instanciar a classe Package sem usar uma with
instrução:
class PackageResource:
def __enter__(self):
class Package:
...
self.package_obj = Package()
return self.package_obj
def __exit__(self, exc_type, exc_value, traceback):
self.package_obj.cleanup()
Você usaria isso da seguinte maneira:
with PackageResource() as package_obj:
# use package_obj