Почему Python не поддерживает операторы switch?

Python
Почему Python не поддерживает операторы switch?

Эта статья из серии «Почему Python», пожалуйста, проверьтеВсе статьи

В этом посте мы поговорим о том, почему Python решил не поддерживать операторы switch.

Почему вы хотите поговорить на эту тему?

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

В дополнение к подробному анализу PEP-275 и PEP-3103, в этой статье также будут представлены последние разработки в Python (PEP-622), то есть синтаксис сопоставления с образцом, который может быть введен.Я считаю, что эта тема расширит кругозор каждого. Это даст вам более полное представление о синтаксисе переключателей.

1. Что такое коммутатор?

Прежде чем мы перейдем к делу, нам нужно поговорить о том, что такое коммутатор?

Некоторые студенты могут подумать об этом впервые...

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

В общем, синтаксис переключателя выглядит следующим образом:

switch(expression){
    case value1:
       // 语句
       break; // 可选
    case value2:
       // 语句
       break; // 可选
    default: // 可选
       // 语句
}

Используя блок-схему для представления, это, вероятно, будет выглядеть так:

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

Большинство языков предоставляют оператор switch или что-то очень похожее, например, в статических языках, таких как C/C++/Java/Go, все они поддерживают конструкции switch-case; в Ruby есть похожая конструкция case-when, в Оболочка В языках есть похожие конструкции case-in, а в Perl есть switch-case-else…

Преимущество оператора switch состоит в том, что он поддерживает структуру выбора с одним условием и множеством ветвей, которая в некоторых случаях более краткая и ясная, чем бинарная структура выбора if-else.

Однако в Python мы не видим switch-case или подобных синтаксических конструкций, почему так?

2. Почему Python не поддерживает переключатель?

В официальной документации есть FAQ, содержащий этот вопрос:Почему в Python нет оператора switch или case?

FAQ — это аббревиатура от Frequently Asked Questions, что означает часто задаваемые вопросы.Официальный список из 27 часто задаваемых вопросов находится здесь:Tickets.WeChat.QQ.com/Yes/Miscellaneous Soldiers I vt4 место…

Документация дает несколько предложений и говорит нам о нескольких альтернативах switch/case:

  • Используйте оператор условного суждения if-elif-else
  • Используя словарь, сопоставьте значения case с вызываемыми функциями
  • Используйте встроенную функцию getattr() для получения определенного метода вызова объекта.

Однако были предложения (а именно PEP-275 и PEP-3103) ввести синтаксис переключения в Python для «Нужно ли и как проводить тестирование дальностид.», и единого мнения не было.

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

Объяснение официального документа «Почему Python не вводит переключатель» на самом деле исходит из мнения отца Python, Гвидо ван Россума в PEP-3103:

Источник:Woohoo.Python.org/Dev/PEPs/PE…

A quick poll during my keynote presentation at PyCon 2007 shows this proposal has no popular support. I therefore reject it.

Я провел быстрый опрос во время основного доклада PyCon 2007, и оказалось, что это предложение не получило широкой поддержки. Поэтому я отверг его.

короче,Было предложено предложение PEP, и реализация грамматики также приняла форму, но основные разработчики, похоже, не пришли к соглашению, что в конечном итоге привело к аборту предложения.

3. Что сказали PEP-275 и PEP-3103?

PEP-3103 был предложен в 2006 г., а PEP-275 — в 2001 г. Их объединяет то, что предлагается определенная необходимость введения оператора switch и анализируются несколько альтернативных реализаций, однако в итоге они были отклонены.

Источник:Woohoo.Python.org/Dev/PEPs/PE…

Итак, давайте сначала рассмотрим, какие обсуждения были сделаны основными разработчиками, и посмотрим, что, если бы Python реализовал структуру переключателя? (PS: PEP также включает в себя другой контент, в этой статье извлекается только часть, непосредственно связанная с коммутатором)

Структура синтаксиса, предложенная PEP-275, выглядит следующим образом:

switch EXPR:
    case CONSTANT:
        SUITE
    case CONSTANT:
        SUITE
    ...
    else:
        SUITE

где еще ветвь необязательна, если она отсутствует и ни одна из предыдущих ветвей не выполняется, ничего не делать. Также константа значения case поддерживает различные типы, поскольку тип выражения expr является динамическим.

В PEP-275 также предлагается сделать так, чтобы switch не поддерживал поведение fall-through, то есть каждая ветвь case была независимой и полной, без необходимости писать break, как в языке C.

В PEP также перечислены некоторые другие проблемы:

  • Повторно используйте существующие ключевые слова, не добавляя «переключатель» и «регистр».
  • Используйте новое ключевое слово, чтобы избежать путаницы с концепцией переключения C
  • Поддерживает одноветвевой выбор нескольких значений (например: case 'a', 'b', 'c': ...)
  • Также рекомендуется поддерживать оценку значения диапазона (например: case 10..14: ...)

В дополнение к предпочтительной схеме этот PEP документирует несколько грамматических схем, которые различаются по стилю:

case EXPR:
    of CONSTANT:
        SUITE
    of CONSTANT:
        SUITE
    else:
        SUITE

case EXPR:
    if CONSTANT:
         SUITE
    if CONSTANT:
        SUITE
    else:
        SUITE

when EXPR:
    in CONSTANT_TUPLE:
        SUITE
    in CONSTANT_TUPLE:
        SUITE
    ...
else:
     SUITE

PEP-275 зафиксировал множество важных идей и проблем, которые заложили хорошую основу для появления PEP-3103.

Итак, давайте посмотрим, что говорит Гвидо PEP-3103.

Сначала он распознал две основные настройки в PEP-275, такие как реализация «неявного разрыва», который не позволяет переходить case-ветвям и передавать управление (другие языки, похоже, требуют явного написания break); является необязательным, повторно используйте ключевое слово else, не вводя «по умолчанию».

Гвидо согласен со стилем, за который выступает PEP-275, но также считает, что его проблема заключается в слишком большом количестве уровней отступов, поэтому рекомендуется уменьшить количество пробелов в отступах в ветвях кода, например, исходный отступ 4 пробелы заменены на отступы в 2 пробела.

PEP-3103 также перечисляет три другие схемы реализации и анализирует их различия и проблемы. Конкретное содержание опущено. Здесь мы только показываем вам их стили:

# case 分支不缩进
switch EXPR:
case EXPR:
    SUITE
case EXPR:
    SUITE
....
else:
    SUITE

# switch 语句后不加冒号
switch EXPR
case EXPR:
    SUITE
case EXPR:
    SUITE
....
else:
    SUITE

# 省略 case 关键字
switch EXPR:
    EXPR:
        SUITE
    EXPR:
        SUITE
    ...
    else:
        SUITE

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

case EXPR, EXPR, ...:

# Guido 优选的
case in EXPR_LIST:

case *EXPR:

case [*]EXPR, [*]EXPR, ...:

case *(EXPR, EXPR, ...):

Проблемы, на которых он сосредоточился, включают: случай, когда результатом выражения в switch является кортеж или итерируемый объект, случай, когда значение case обрабатывается как распакованный кортеж, операция звездочки «*» в ветви case ...

Затем Гвидо уделил много внимания анализу того, как реализовать переключатель, и обсудил следующие основные идеи:

  • Определите оператор switch с эквивалентной цепочкой if-elif (возможно, с некоторыми оптимизациями)
  • То же, что и выше, за исключением того, что все выражения должны быть хешируемыми.
  • См. также отправку предварительно вычисленных словарей

В этой части PEP очень много контента, потому что Гвидо также рассматривал несколько путей реализации для каждой идеи, что привело после комплексного анализа к его выводу: Еще слишком рано решать, утро).

После прочтения PEP-3103 у меня сложилось общее впечатление: идеи Гвидо очень разнообразны и богаты слоями, но ему не хватает его «быстрого» понимания при столкновении с другими проблемами.

То есть во многих возможных сценариях он пытался охватить все, и в конце концов не смог убедить себя принять диктаторское решение. Сопротивление исходит главным образом от него самого, а не от других.

Однако причина этого может быть связана с его предустановленной позицией: он, кажется, думает, что «Python в порядке без оператора switch», поэтому, несмотря на написание длинного PEP, он только усложняет проблему и ставит проблему. на удержание.

В конце концов, он провел мелкомасштабное расследование на PyCon, тем самым "обоснованно" отвергнув инициированное им политическое деяние, пытаясь заткнуть всем рот...

4. Будет ли в будущем оператор switch?

Это сводится к следующим причинам, по которым в Python нет оператора switch:Детали реализации / функциональные точки переключателя не доработаны, ни один переключатель не годится, есть другие хорошие способы заменить переключатель, небольшое своеволие Гвидо...

Тем не менее, мы все еще должны спросить:Будет ли в будущем оператор switch? Или аналогичная многоотраслевая структура выбора?

К чему этот вопрос? Причина в том, что слишком много языков имеют собственный оператор switch, а также есть много людей, пытающихся написать библиотеки, обеспечивающие функциональность переключателя (помню вPyCoder's Weeklyвидел дважды).

Я (кот Python) сам никогда не любил переключатель, и почти наверняка в Python не будет переключателя в будущем, однако он, вероятно, представит более сложную синтаксическую структуру, похожую на переключатель!

В июне 2020 года был предложен PEP-622, который предлагает ввести синтаксис сопоставления с образцом в таких языках, как Scala, Erlang и Rust (pattern matching).

По состоянию на октябрь 2020 года это политически значимое лицо было разделено на три других политически значимых лица (634–636), все из которых в настоящее время находятся на стадии проекта. Учитывая участие основных разработчиков и обсуждение темы, весьма вероятно, что эти предложения будут реализованы в будущих версиях (например, в 3.10, которая находится в разработке).

Взяв в качестве примера усредненную функцию, синтаксис сопоставления с образцом можно реализовать следующим образом:

def average(*args):
    match args:
        case [x, y]:           # captures the two elements of a sequence
            return (x + y) / 2
        case [x]:              # captures the only element of a sequence
            return x
        case []:
            return 0
        case x:                # captures the entire sequence
            return sum(x) / len(x)

Структура match-case похожа на структуру switch-case, но она основана на шаблонах, а не на выражениях, поэтому необходимо учитывать больше деталей и расширять область применения.

Читателям, интересующимся этой темой, рекомендуется проконсультироваться с этими новыми PEP.

Наконец, вернемся к вопросу в заголовке:Почему Python не поддерживает операторы switch?

В FAQ официальной документации есть ответ на этот вопрос, сообщающий нам, что есть несколько хороших альтернатив, а также оставляющий подсказку: было предложение PEP ввести переключатель, но оно не было успешно реализовано.

Вслед за этой веткой в ​​этой статье разобраны два документа PEP-275 и PEP-3103 и показаны различные решения переключения, предложенные в сообществе Python, а также множество нерешенных проблем.

Наконец, мы также следили за последней динамикой PEP-622, и похоже, что синтаксис switch с двойным соответствием, как ожидается, будет введен в Python! Тема переключения вроде бы подходит к концу, но назревает другая большая тема!

Эта статья относится к серии «Почему Python» (подготовленной Python Cat), которая в основном посвящена таким темам, как синтаксис, дизайн и разработка Python, и пытается показать очаровательное очарование Python, начиная с вопросов «почему». Все статьи будут заархивированы на Github, всем желающим поставить маленькую звездочку, адрес проекта:GitHub.com/Китайский макияж…