简体   繁体   中英

What does a star (asterisk) do in f-string?

In the python document 2.4.3. Formatted string literals , it seems possible to write a star followed by an expression in a f-string's {} , but I cannot find how to use that.

What's that and how I can use it? Is it documented somewhere?

To be exact, this is regarding "*" or_expr part of the following 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

I tried it in REPL, but it causes an error.

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

There are two alternatives for f_expression : a comma separated list of or_expression s, optionally preceded by asterisks, or a single yield_expression . Note the yield_expression does not allow an asterisk.

I assume the intention was that the comma-separated list alternative is only chosen when there's at least one comma, but the grammar doesn't actually say that. I feel like the repetition operator at the end should have been a + instead of a * .

So f"{*1}" would be a syntax error because there's an asterisk, but no comma. f"{*1,*2}" is syntactically valid, but a type error because 1 and 2 aren't iterable. f"{*[1], *[2]}" is valid and acts the same as f"{1,2}" . So the asterisk is allowed because it acts as the splat operator in tuples, which can be written without parentheses in f-expressions.

Note that using or_expr as the operand to * does not mean that a bitwise or-operator has to be used there - it just means that the bitwise or-operator is the first operator in the precedence-hierachy that would be allowed as an operand to * . So it's just about setting the precedence of prefix * vs. other expressions. I believe or_expression is consistently used as the operand to prefix * everywhere in the grammar (that is, everywhere where prefix * is followed by an expression as opposed to a parameter name).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM