Стандартная практика проверки ошибок 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)

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

ii) Используйте assert для проверки предварительного условия:

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

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

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

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


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

4 ответа

Если все, что вы хотите сделать, это вызвать исключение, используйте опцию 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-блок.

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

from __future__ import with_statement

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

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

Формальная семантика assert:

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

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

  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: Нет такого файла или каталога

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

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

Другие вопросы по тегам