Стандартная практика проверки ошибок 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:
Условие может оцениваться или не оцениваться (поэтому не полагайтесь на побочные эффекты выражения).
Если условие истинно, выполнение продолжается.
Не определено, что произойдет, если условие ложно.
Следующее следует из примера ~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
,
Использование утверждений слишком хрупко, потому что они могут быть отключены.