Что делает звезда (звездочка) в струнной? - PullRequest
15 голосов
/ 01 мая 2019

В документе python 2.4.3. Отформатированные строковые литералы , кажется возможным написать звезду с последующим выражением в f-строке {}, но я не могу найти, как это использовать.

Что это такое и как я могу это использовать? Это где-то задокументировано?

Если быть точным, то это относится к "*" or_expr части следующего BNF .

f_string          ::=  (literal_char | "{{" | "}}" | replacement_field)*
replacement_field ::=  "{" f_expression ["!" conversion] [":" format_spec] "}"
f_expression      ::=  (conditional_expression | "*" or_expr)
                         ("," conditional_expression | "," "*" or_expr)* [","]
                       | yield_expression

Я попробовал это в REPL, но это вызывает ошибку.

>>> l = [1, 2, 3]
>>> f"{l}"
'[1, 2, 3]'
>>> f"{*l}"
  File "<stdin>", line 1
SyntaxError: can't use starred expression here

1 Ответ

8 голосов
/ 01 мая 2019

Существует две альтернативы для f_expression: список с разделителями-запятыми or_expression с, перед которыми могут стоять звездочки, или одиночный yield_expression. Обратите внимание, что yield_expression не позволяет использовать звездочку.

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

Так что f"{*1}" будет синтаксической ошибкой, потому что есть звездочка, но нет запятой. f"{*1,*2}" синтаксически допустимо, но ошибка типа, потому что 1 и 2 не повторяемы. f"{*[1], *[2]}" действителен и действует так же, как f"{1,2}". Таким образом, звездочка разрешена, потому что она действует как оператор splat в кортежах, которые могут быть записаны без скобок в f-выражениях.

Обратите внимание, что использование or_expr в качестве операнда для * не означает, что там должен использоваться побитовый оператор или - он просто означает, что побитовый оператор или является первым оператором в иерархии предшествования, который будет разрешено в качестве операнда для *. Так что это просто установка приоритета префикса * по сравнению с другими выражениями. Я считаю, что or_expression последовательно используется в качестве операнда для префикса * везде в грамматике (то есть везде, где за префиксом * следует выражение, а не имя параметра).

...