Я получил:
return r.group() if r := re.match(rx,l) else None
^
SyntaxError: неверный синтаксис
тогда как
return r.group() if (r := re.match(rx,l)) else None
принято.
Что недопустимо в синтаксисе первого? А какое еще толкование, кроме второго, такое, чтобы оно не было однозначным?






См. таблицу приоритета операторов — используя скобки для выделения приоритета, первое выражение:
return r.group() if (r := (re.match(rx,l) else None))
^^^^^^^^^^^^^^^^^^^^^^^^
Очевидно, что это скорее синтаксическая ошибка, чем двусмысленность, но интерпретатор Python не может просто свободно переопределить приоритет, чтобы выбрать интерпретацию, которая имеет смысл.
Приоритет операторов вступает в игру только тогда, когда структура уже определена как синтаксически допустимая и существует семантическая неоднозначность. Он никогда не сможет сделать структуру синтаксически недействительной.
Я думаю, что синтаксический анализ не поддерживается этой таблицей приоритета операторов, потому что, хотя таблица имеет if – else предшествовавший :=, сама по себе она не имеет else предшествующего :=.
Ограничение допустимых мест, в которых может использоваться оператор моржа («выражение присваивания» для тех, кто убил своего внутреннего ребенка), было в основном выборным. Они не хотели, чтобы он заменял = для присваивания или привыкал постоянно сжимать несколько строк кода в одну ради развлечения, поэтому они наложили ограничения на его синтаксис, которые делают его неудобным за пределами случаев, для которых он действительно был разработан. . Самым большим ограничением было то, что они требовали скобки в тех случаях, когда в этом нет особой необходимости (например, наиболее очевидным случаем является то, что язык мог тривиально реализовать это так, чтобы x := 1 сам по себе работал, но решил не делать этого).
Спецификация грамматики языка описывает точные правила (выделено нами):
Выражения присваивания должны быть заключены в круглые скобки при использовании в качестве операторов выражения и при использовании в качестве подвыражений в выражениях среза, условных, лямбда-выражениях, выражениях с ключевым словом-аргументом и понимании-если, а также в выражениях
assert,withиassignment. Во всех остальных местах, где их можно использовать, скобки не требуются, в том числе в операторахifиwhile.
По сути, моржи без скобок по определению несовместимы с условными выражениями, потому что так сказали разработчики языка Python.
Спасибо за это отличное объяснение. «в основном преднамеренная вещь». Попался. для меня это частично случайно. :)
«Они накладывают ограничения на его синтаксис, которые делают его неудобным за пределами случаев, для которых он действительно был разработан». Попался. Я думаю, мы должны быть благодарны, что они не просто записали это :)
@ChrisJJ: Я не собираюсь говорить, что что-то из этого было случайностью (непреднамеренные части - это случаи, когда действительно были проблемы, которые требовали скобок, чтобы избежать двусмысленности в грамматике, или технически однозначное, но чрезвычайно запутанное поведение) . Но, конечно, вы воспринимаете это как хотите. :-)
«Я не собираюсь говорить, что это был несчастный случай». Хорошо. Я соглашусь на ваше «непреднамеренное» :) «(непреднамеренные части — это случаи, когда действительно были проблемы, которые требовали скобок, чтобы избежать двусмысленности в грамматике». Думаю, мы никогда не узнаем, почему эти законные случаи заслуживали меньшего внимания, чем дела о «развлечениях».
@ChrisJJ: Решил перейти от «намеренного» (что, как вы говорите, происходит практически автоматически, если только они не плохо справляются со своей работой) на «выборное»; они могли бы сделать это законным во многих других контекстах, иногда с меньшими усилиями, чем разрешить это, и решили явно запретить это во многих из них.
Это не результат выбора приоритета. Природа
on_true if cond else on_falseтакова, что условная часть выражения по своей сути однозначна; к тому времени, когда вы увидитеif, вы знаете, что находитесь в условной части, которую можно закончить только с помощьюelse(Ccond ? on_true : on_falseаналогична, где частьon_trueограничена достаточно хорошо, чтобы вы могли делать некоторые вещи там, не беспокоясь о скобках для приоритета, которые не будут работать в частяхcondилиon_false). Python намеренно решил сделать моржей без скобок незаконными.