Pergunta

Para encurtar a história, eu tenho um aplicativo Python substancial que, entre outras coisas, faz outcalls para "losetup", "montar", etc. no Linux. Essencialmente consumindo recursos do sistema que deve ser liberado quando completa.

Se o meu aplicativo falhar, quero garantir que esses recursos do sistema estão devidamente liberado.

Será que faz sentido para fazer algo como o seguinte?

def main():
    # TODO: main application entry point
    pass

def cleanup():
    # TODO: release system resources here
    pass

if __name__ == "__main__":
    try:
        main()
    except:
        cleanup()
        raise

Isto é algo que geralmente é feito? Existe uma maneira melhor? Talvez o destruidor em uma classe singleton?

Foi útil?

Solução

Eu gosto de manipuladores de exceção de nível superior em geral (independentemente da linguagem). Eles são um ótimo lugar para recursos de limpeza que não pode ser imediatamente relacionadas com recursos consumidos dentro do método que gera a exceção.

É também um lugar fantástico para log essas exceções se você tem um tal quadro no lugar. manipuladores de nível superior vai pegar essas exceções bizarras você não planeja e deixá-lo corrigi-los no futuro, caso contrário, você nunca pode saber sobre eles em tudo.

Apenas tome cuidado para que o manipulador de nível superior não lançar exceções!

Outras dicas

A destructor (como em um método __del__) é uma má idéia, já que estes não são garantidos para ser chamado. O módulo atexit é uma abordagem mais segura, embora estes ainda não dispara se o Python intérprete acidentes (em vez do aplicativo Python), ou se os._exit () é usado, ou o processo é morto de forma agressiva, ou a reinicialização da máquina. (Claro, o último item não é um problema no seu caso.) Se o seu processo é crash-prone (ele usa módulos de extensão de terceiros inconstantes, por exemplo) você pode querer fazer a limpeza em um processo pai simples para mais isolamento.

Se você não está realmente preocupado, utilizar o módulo atexit.

ampla aplicação manipulador é bom. Eles são ótimos para registro. Apenas certifique-se que a aplicação de largura é durável e é pouco provável que falhar em si.

Se você usar classes, você deve liberar os recursos que alocam em seus destruidores em vez disso, é claro. Use o try:. Em toda a aplicação apenas se você quiser liberar recursos que ainda não estão liberados pelos destruidores das suas classes

E, em vez de usar um pega-tudo, exceto :, você deve usar o seguinte bloco:

try:
    main()
finally:
    cleanup()

Isso irá garantir a limpeza de uma maneira mais Python.

Isso parece ser uma abordagem razoável, e muito mais simples e confiável do que um destruidor em uma única classe. Você também pode olhar para o módulo " atexit ". (Pronuncia-se "na saída", não "um tex-lo", ou algo assim. Eu confuso que por um longo tempo.)

Considere escrever um gerente de contexto e usando o com a declaração.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top