Оператор case: вариант по умолчанию для выявления ошибок

Если раздел по умолчанию оператора case (либо заменяющего его набора elif) не имеет назначения в текущем алгоритме, то генерируйте в нём исключение. Так при корректной работе кода вариант по умолчанию не подразумевается, значит если он всё-таки будет выполнен, то случилось что-то непредвиденное. Эту ситуацию полезно обнаружить как можно раньше.

Рассмотрим несколько вариантов функции day_of_week которая принимает в качестве аргумента номер дня недели и возвращает его название. Нумерация дней недели начинается с нуля.

В первом случае ситуация когда передан неверный номер не обрабатывается.

def day_of_week1(num):
    if num == 0:
        dayName = 'Понедельник'
    elif num == 1:
        dayName = 'Вторник'
    elif num == 2:
        dayName = 'Среда'
    elif num == 3:
        dayName = 'Четверг'
    elif num == 4:
        dayName = 'Пятница'
    elif num == 5:
        dayName = 'Суббота'
    elif num == 6:
        dayName = 'Воскресенье'

    return dayName

Если передать неверный номер то произойдет исключение, но понять его причину будет сложно.

UnboundLocalError: local variable 'dayName' referenced before assignment

В случае если добавить вариант по умолчанию с каким-то значением то проблема только усугубляется.

def day_of_week2(num):
    if num == 0:
        dayName = 'Понедельник'
    elif num == 1:
        dayName = 'Вторник'
    elif num == 2:
        dayName = 'Среда'
    elif num == 3:
        dayName = 'Четверг'
    elif num == 4:
        dayName = 'Пятница'
    elif num == 5:
        dayName = 'Суббота'
    elif num == 6:
        dayName = 'Воскресенье'
    else:
        dayName = 'Неверный день недели'

    return dayName

Предположим эта функция используется для составления отчёта и в неё попало ошибочное число номера дня. Теперь проблема не будет обнаружена сразу при генерации отчета, её получится найти только если просмотреть отчёт, что снижает вероятность обнаружения ошибки.

Генерация исключения в варианте по умолчанию позволяет с одной стороны быстрее обнаружить проблему, а с другой по исключению догадаться о возможных источниках проблемы.

def day_of_week3(num):
    if num == 0:
        dayName = 'Понедельник'
    elif num == 1:
        dayName = 'Вторник'
    elif num == 2:
        dayName = 'Среда'
    elif num == 3:
        dayName = 'Четверг'
    elif num == 4:
        dayName = 'Пятница'
    elif num == 5:
        dayName = 'Суббота'
    elif num == 6:
        dayName = 'Воскресенье'
    else:
        raise ValueError('Неверный день недели')

    return dayName

Сообщение об исключении теперь значительно более понятное:

ValueError: Неверный день недели

Дополнительно улучшить код можно переписав его с помощью блоков с выходом:

def day_of_week4(num):
    if num == 0:
        return 'Понедельник'
    if num == 1:
        return 'Вторник'
    if num == 2:
        return 'Среда'
    if num == 3:
        return 'Четверг'
    if num == 4:
        return 'Пятница'
    if num == 5:
        return 'Суббота'
    if num == 6:
        return 'Воскресенье'

    raise ValueError('Неверный день недели')

Использование конструкции switchopen in new window ничего принципиально не меняет.

def day_of_week5(num):
    match num:
        case 0:
            return 'Понедельник'
        case 1:
            return 'Вторник'
        case 2:
            return 'Среда'
        case 3:
            return 'Четверг'
        case 4:
            return 'Пятница'
        case 5:
            return 'Суббота'
        case 6:
            return 'Воскресенье'
        case _:
            raise ValueError('Неверный день недели')

Ссылки

Ссылки на эту заметку

Эта заметка на GitHub

Обсудить на форуме

Последниее изменение: