Проверка стандартной ошибки Python

У меня вопрос относительно проверки ошибок в Python. Скажем, у меня есть функция, которая принимает путь к файлу в качестве входного файла:

def myFunction(filepath):
    infile = open(filepath)
    #etc etc...

Одним из возможных предварительных условий было бы то, что файл должен существовать.

Есть несколько возможных способов проверить это предварительное условие, и мне просто интересно, что это лучший способ сделать это.

i) Проверьте с помощью оператора if:

if not os.path.exists(filepath):
    raise IOException('File does not exist: %s' % filepath)

Это то, что я обычно делал, хотя одно и то же IOException было бы поставлено Python, если файл не существует, даже если я его не поднимаю.

ii) Используйте assert, чтобы проверить предварительное условие:

assert os.path.exists(filepath), 'File does not exist: %s' % filepath

Использование утверждений, по-видимому, является "стандартным" способом проверки пре/постусловий, поэтому у меня возникает соблазн использовать их. Тем не менее, возможно, что эти утверждения отключены, когда во время выполнения используется флаг -o, что означает, что эта проверка может быть отключена, и это кажется рискованным.

iii) Не обрабатывайте предварительное условие вообще

Это связано с тем, что если путь к файлу не существует, в любом случае генерируется исключение, и сообщение об исключении будет достаточно подробным для того, чтобы пользователь знал, что файл не существует.


Мне просто интересно, какая из перечисленных выше - стандартная практика, которую я должен использовать для своих кодов.

Ответы

Ответ 1

Если все, что вы хотите сделать, это поднять исключение, используйте опцию iii:

def myFunction(filepath):
    with open(filepath) as infile:
        pass

Для обработки исключений особым образом используйте блок try...except:

def myFunction(filepath):
    try:
        with open(filepath) as infile:
            pass
    except IOError:
        # special handling code here

Ни при каких обстоятельствах не рекомендуется сначала проверять наличие файла (опция i или ii), поскольку в промежутке между тем, когда происходит проверка или утверждение, и когда python пытается открыть файл, возможно что файл может быть удален или изменен (например, с символической ссылкой), что может привести к ошибкам или дыре в безопасности.

Кроме того, с Python 2.6 наилучшей практикой при открытии файлов является использование синтаксиса with open(...). Это гарантирует, что файл будет закрыт, даже если исключение происходит внутри with -block.

В Python 2.5 вы можете использовать синтаксис with, если префикс script с

from __future__ import with_statement

Ответ 2

Определенно не используйте assert. Утверждения должны только терпеть неудачу, если код неверен. Внешние условия (например, отсутствующие файлы) не должны проверяться с помощью утверждений.

Как отмечали другие, утверждения могут быть отключены.

Формальная семантика утверждения:

  • Условие может быть или не быть оценено (поэтому не полагайтесь на побочные эффекты выражения).

  • Если условие истинно, выполнение продолжается.

  • undefined что происходит, если условие ложно.

Подробнее об этой идее.

Ответ 3

Далее следует пример ~ unutbu. Если файл не существует или какой-либо другой тип ошибки ввода-вывода, имя файла также передается в сообщении об ошибке:

path = 'blam'
try:
    with open(path) as f:
        print f.read()
except IOError as exc:
    raise IOError("%s: %s" % (path, exc.strerror))

= > IOError: blam: Нет такого файла или каталога

Ответ 4

Я думаю, вы должны пойти со смесью iii) и i). Если вы знаете, что этот python будет генерировать исключение (т.е. Случай iii), то пусть это сделает python. Если есть другие предпосылки (например, требуемые вашей бизнес-логикой), вы должны бросить собственные исключения, возможно, даже получить из Exception.

Использование утверждений слишком хрупкое imho, потому что они могут быть отключены.