Если вложенность пунктов против каскада вернуться против утверждения


Когда отрицательная оценка в предложении 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 5

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