Если вложенность пунктов против каскада вернуться против утверждения
Когда отрицательная оценка в предложении if вызовет вызов return
внутри функции / метода, что более рекомендуется в Python, чтобы вложить предложения if или использовать обратную оценку и вызвать функцию return? например:
if required_condition_1:
if required_condition_2:
if required_condition 3:
pass
return 'error for condition 3'
return 'error for condition 2'
return 'error for condition 1'
Или:
if not required_condition_1:
# preparation...
return 'error for condition 1'
if not required_condition_2:
# preparation...
return 'error for condition 2'
if not required_condition_3:
# preparation...
return 'error for condition 3'
# if runtime reaches this point it means that it has passed all conditions
Представьте, что вы должны зарегистрировать пользователя, и вам нужно выполнить различные условия. Пользователь будет зарегистрирован только в том случае, если все они удовлетворены, но сообщения об ошибках зависят от того, какое условие не выполняется.
Я предполагаю, что в другие обстоятельства, как пользователь упоминает в разделе ответов, другие действия могут применяться, если определенное условие не выполняется. Тогда я думаю, что мне следует вложить в гнездо "если". Однако я буду возвращать только сообщение об ошибке, поэтому я думаю, что второй вариант предпочтительнее.
Я также думал об утверждении:
try:
assert(required_condition_1)
try:
assert(required_condition_2)
# do tasks
except AssertionError:
# error for condition 2
except AssertionError:
# error for condition 1
Хотя я думаю, что этот последний способ не очень рекомендуется, как при лечении исключений. Также как пользователь SO упоминает :
Если код верен, исключение одно-событийных сбоев, аппаратных сбоев и такое, никакое утверждение никогда не подведет. Вот почему поведение программа для конечного пользователя не должна быть затронута. Тем более, утверждение не может потерпеть неудачу даже в исключительных программных условиях. Это просто такого никогда не бывает. Если это произойдет, программист должен быть отключен для него.
Я знаю, что это может показаться в первую очередь основанным на мнении , но для меня это не , поскольку все языки имеют правила стиля, которые создание более устойчивой, масштабируемой и читаемой среды в зависимости от ее характеристик и функциональных возможностей. Я хотел бы знать, что если есть рекомендуемый способ лечения этого вопроса внутри методов и самое главное, почему.
2 ответа:
Хотя это можно рассматривать как основанное на мнении, я думаю, что объективно второй способ кажется гораздо более читаемым.
В вашем первом примере кто-то, читающий ваш код, должен был бы расшифровать, что каждое утверждение логически не связано с тем, в которое оно вложено, что-то, что вы не хотите, чтобы произошло. В общем, вложенные блоки подразумевают некую наследуемую логику.Второй пример написан гораздо аккуратнее и не требует много размышлений, чтобы осознать поток логики. Вместо того чтобы продвигаться все глубже и глубже, чем больше условий вы хотите применить, логический поток, кажется, подразумевает, что каждое должно быть удовлетворено независимо.
Первый стиль имеет свои варианты использования, только не для данной задачи под рукой: проверка условий.
Что касается вашего второго вопроса, использование asserts в этом случае использования не будет считаться уместным. Как правило, используйте
assert
только тогда, когда что-то, что никогда не должно пойти не так, но очень важно для выполнение программы, идет не так. Одно из наиболее очевидных применений-это написание тестовых случаев, функция должна давать определенный результат, и это очень плохо, если она не дает вам этот результат.Исключения предназначены для вещей, которые вы могли бы ожидать, чтобы пойти не такнапример деление на ноль ошибок, ошибок атрибутов и тому подобное при работе с пользовательским вводом.
Как Зияд Edher ответил, второй является более удобочитаемым:
if not required_condition_1: # preparation... return 'error for condition 1' if not required_condition_2: # preparation... return 'error for condition 2' if not required_condition_3: # preparation... return 'error for condition 3'
И, если вы хотите иметь только 1
return
, то:if not required_condition_1: # preparation... _error = 'error for condition 1' elif not required_condition_2: # preparation... _error = 'error for condition 2' elif not required_condition_3: # preparation... _error = 'error for condition 3' else: _error = None return _error