Как вы тестируете ошибку file.read () в Python? - PullRequest
4 голосов
/ 17 декабря 2008

У меня есть следующий код (адаптированный из примера, приведенного в Dive Into Python ), который считывает все содержимое файла в буфер.

buffer = ""

try:
    file = open(postFileName, 'rU')
    try:
        # Read the entire POST log file into a buffer
        buffer += file.read()
    finally:
        file.close()
except IOError:
    buffer += "The POST file could not be opened."

Что беспокоит меня об этом коде, так это внутренний блок try / finally без блока исключения. Нужен ли там блок кроме? Может ли звонок на read() завершиться неудачно после того, как звонок на open() был успешным? Я знаю, что попытка-исключение-наконец теперь унифицирована, поэтому добавление одного, по крайней мере, синтаксически, не проблема.

Если я добавлю блок исключения, при каких условиях он будет выполняться, и как мне написать тест, чтобы убедиться, что он работает в этих условиях?

Кроме того, если мне не нужен блок исключения, тогда зачем вообще нужен внутренний блок try / finally?

Ответы [ 4 ]

7 голосов
/ 17 декабря 2008

Я считаю, что, наконец, блоки часто используются слишком часто. Закрытие файла (и несколько других подобных шаблонов) настолько важны, что Python 3.0 будет иметь оператор с , чтобы просто покрыть эту базу чуть менее неясным способом.

  • Нужно ли кроме как, наконец,?

    Это затрагивает запутанную природу этого конкретного примера и почему они добавили оператор с .

    Наконец, 1014 * выполняет очистку «независимо от того, что». Исключение или отсутствие исключения: finally всегда выполняется.

  • Может ли вызов read () завершиться неудачно после успешного вызова open ()?

    Все вызовы ОС, все вызовы ввода / вывода (почти все) могут вызывать исключение. Все виды плохих вещей могут произойти после открытия и перед прочтением.

  • Если я добавлю , за исключением блока, при каких условиях он будет выполняться?

    Читайте файлы. Есть много глупых ошибок ввода-вывода, которые могут возникнуть между открытием и чтением. Также ознакомьтесь со встроенными исключениями. https://docs.python.org/2/library/exceptions.html

  • Как мне написать тест, чтобы убедиться, что он работает в таких условиях?

    Вам понадобится фиктивный объект файла. Этот объект будет реагировать на open, но поднимает IOError или OSError на каждые read.

  • Если мне не нужен блок кроме, тогда зачем вообще нужен внутренний блок try / finally?

    Cleanup. finally будет выполнено независимо от того, какое исключение возбуждено.

Попробуй это. Посмотрите, что он делает.

try:
 raise OSError("hi mom")
finally:
 print "Hmmm"
3 голосов
/ 17 декабря 2008

Я не согласен с другими ответами, в которых упоминается объединение блоков try / кроме / finally. Это изменило бы поведение, так как вы не хотели бы, чтобы блок finally пытался закрыть файл, если открытие не удалось. Разделенные блоки здесь корректны (хотя, возможно, лучше использовать новый синтаксис "with open(filename,'rU') as f").

Есть причины, по которым read () может завершиться ошибкой. Например, данные могут быть слишком большими, чтобы поместиться в память, или пользователь мог сообщить об прерывании с помощью control-C. Эти случаи не будут обнаружены IOError, но будут оставлены для обработки (или нет) вызывающей стороной, которая может захотеть сделать разные вещи в зависимости от характера приложения. Тем не менее, код все еще обязан очистить файл, даже если он не имеет дело с ошибкой, следовательно, в конечном итоге без исключения.

0 голосов
/ 17 декабря 2008

Погуглив немного, получил это Единая попытка / исключая / окончательно

Надеюсь, это поможет;)

0 голосов
/ 17 декабря 2008

В последней версии Python вам не нужно вкладывать try-кроме и try-finally. try-Кроме-наконец был унифицирован:

try:
  non_existing_var
except:
  print 'error'
finally:
  print 'finished'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...