Здесь вы смешиваете две вещи: утверждения и логику на основе EAFP.
Утверждения используются для проверки контракта функций, то есть его пред- и постусловий, а иногда и его инвариантов. Они гарантируют, что функция будет использоваться так, как она должна использоваться. Однако они не предназначены для потока кода, поскольку полностью прерывают выполнение при ошибке. Типичным примером является проверка None
аргументов в вызовах функций.
В Python вы обычно избегаете слишком частого использования утверждений. Как правило, вы должны ожидать, что пользователи вашего кода будут использовать его правильно. Например, если вы документируете функцию, которая принимает аргумент, отличный от None
, то нет необходимости в утверждении, подтверждающем это. Вместо этого просто ожидайте, что есть значение. Если есть ошибка из-за значения None, то она все равно всплывет, чтобы пользователь знал, что он сделал что-то не так. Но не нужно все время проверять.
Теперь EAFP — это нечто другое. Он используется в потоке управления, или, скорее, он позволяет избежать дополнительного потока управления в пользу того, чтобы ожидать, что все будет правильно, и вместо этого перехватывать исключения, если они неверны. Типичным примером, показывающим разницу, является доступ к ключу в словаре:
# LBYL
if key in dic:
print(dic[key])
else:
handleError()
# EAFP
try:
print(dic[key])
except KeyError:
handleError()
Теперь это выглядит очень похоже, хотя вы должны иметь в виду, что решение LBYL проверяет словарь дважды. Как и в случае со всем кодом, перехватывающим исключения, вы должны делать это только в том случае, если отсутствие ключа является исключительным случаем. Поэтому, если обычно предоставленный ключ не содержится в словаре, то это EAFP, и вы должны просто получить к нему прямой доступ. Если вы не ожидаете, что ключ будет присутствовать в словаре, то вам, вероятно, следует сначала проверить его существование (хотя исключения в Python дешевле, они все же не бесплатны, поэтому оставьте их для исключительных случаев).
Преимущество EAFP здесь также заключается в том, что глубже в логике вашей библиотеки или приложения, где key
приходит сверху, вы можете просто предположить, что здесь был передан действительный ключ. Таким образом, вам не нужно перехватывать здесь исключения, а просто позвольте им подняться до более высокой точки в вашем коде, где вы затем сможете обработать ошибку. Это позволяет вам иметь низкоуровневые функции, полностью свободные от таких проверок.
person
poke
schedule
02.10.2015
try...except
? Должен ли я изменить вопрос? - person n1000   schedule 02.10.2015assert
. Видимо, я не использовал их должным образом в прошлом... - person n1000   schedule 02.10.2015