Эта статья из серии «Почему 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/Китайский макияж…