У меня есть вопрос относительно проверки ошибок в 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 os.path.exists(filepath), 'File does not exist: %s' % filepath
Используя утверждает, кажется, "стандартный" способ проверить на пред/постусловия, таким образом, я испытываю желание использовать их. Однако возможно, что они утверждают, выключены, когда флаг-o используется во время выполнения, что означает, что эта проверка могла бы потенциально быть выключена, и это кажется опасным.
iii) Не обрабатывайте предварительное условие вообще
Это вызвано тем, что, если filepath не существует, будет исключение, сгенерированное так или иначе, и сообщение об исключении подробно изложено достаточно, чтобы пользователь знал, что файл не существует
Я просто задаюсь вопросом, какое из вышеупомянутого является общепринятой практикой, которую я должен использовать для своих кодов.
Если все, что вы хотите сделать, это вызвать исключение, используйте опцию 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, при открытии файлов рекомендуется использовать с синтаксисом open (...)
. Это гарантирует, что файл будет закрыт, даже если исключение произойдет внутри с
-блоком.
В Python 2.5 вы можете использовать синтаксис с
, если перед скриптом укажите
from __future__ import with_statement
Следующий пример расширяет пример ~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: No such file or directory
Я думаю, что вам следует использовать сочетание iii) и i). Если вы точно знаете, что python выбросит исключение (т.е. случай iii), то позвольте python сделать это. Если есть какие-то другие предварительные условия (например, требуемые вашей бизнес-логикой), вам следует создавать собственные исключения, возможно, даже производные от Exception
.
Использование утверждений слишком хрупко, имхо, потому что они могут быть отключены.
Определенно не используйте утверждения. Утверждения должны срабатывать только в том случае, если код неверен. Внешние условия (например, отсутствие файлов) не должны проверяться с помощью утверждений.
Как отмечали другие, утверждения можно отключить.
Формальная семантика assert такова:
Условие может быть оценено или не оценено (поэтому не полагайтесь на побочные эффекты выражения).
Если условие истинно, выполнение продолжается.
Не определено, что произойдет, если условие ложно.