ti-enxame.com

Usando a instrução python "with" com o bloco try-except

Essa é a maneira correta de usar a instrução python "with" em combinação com um bloco try-except ?:

try:
    with open("file", "r") as f:
        line = f.readline()
except IOError:
    <whatever>

Se for, considere a maneira antiga de fazer as coisas:

try:
    f = open("file", "r")
    line = f.readline()
except IOError:
    <whatever>
finally:
    f.close()

O principal benefício da declaração "with" aqui é que podemos nos livrar de três linhas de código? Não me parece tão atraente para este caso de uso (embora eu entenda que a instrução "with" tem outros usos).

EDIT: A funcionalidade dos dois blocos de código acima é idêntica?

EDIT2: As primeiras respostas falam geralmente sobre os benefícios de usar "with", mas essas parecem ser de benefício marginal aqui. Todos nós temos (ou deveria ter) chamado explicitamente f.close () por anos. Suponho que um benefício é que os codificadores desleixados se beneficiarão do uso de "with".

86
gaefan
  1. Os dois blocos de código que você forneceu são não equivalentes
  2. O código que você descreveu como a maneira antiga de fazer as coisas tem um erro sério: no caso de falha na abertura do arquivo, você receberá uma segunda exceção no finally _ porque f não está vinculado.

O código equivalente de estilo antigo seria:

try:
    f = open("file", "r")
    try:
        line = f.readline()
    finally:
        f.close()
except IOError:
    <whatever>

Como você pode ver, a instrução with pode tornar as coisas menos propensas a erros. Nas versões mais recentes do Python (2.7, 3.1), você também pode combinar várias expressões em uma instrução with. Por exemplo:

with open("input", "r") as inp, open("output", "w") as out:
    out.write(inp.read())

Além disso, eu pessoalmente considero um mau hábito capturar qualquer exceção o mais cedo possível. Este não é o objetivo das exceções. Se a função IO que pode falhar fizer parte de uma operação mais complicada, na maioria dos casos, o IOError deve interromper toda a operação e, portanto, ser tratado em um nível externo. Usando as instruções with, você pode se livrar de todas essas instruções try...finally nos níveis internos.

126
Bernd Petersohn

Se o conteúdo do bloco finally for determinado pelas propriedades do objeto de arquivo que está sendo aberto, por que não foi o implementador do objeto de arquivo quem gravou o bloco finally? Esse é o benefício da instrução with, muito mais do que salvar três linhas de código nessa instância específica.

E sim, a maneira como você combinou with e try-except é praticamente a única maneira de fazer isso, pois erros excepcionais causados ​​na instrução open em si não podem ser capturados no bloco with.

6
Peter Milley

Eu acho que você entendeu errado a afirmação "with" de que isso apenas reduz as linhas. Realmente inicializa e lida com desmontagem.

No seu caso "com" faz

  • abra um arquivo
  • processar seu conteúdo e
  • certifique-se de fechá-lo.

Aqui está o link para entender a declaração "com": http://effbot.org/zone/python-with-statement.htm

Editar: Sim, o uso de "com" está correto e a funcionalidade dos dois blocos de código é idêntica. Pergunta sobre por que usar "with"? é por causa dos benefícios que você obtém com isso. como você mencionou sobre a falta acidental de f.close ().

1
YoK