【问题标题】:What does a star (asterisk) do in f-string?f-string 中的星号(星号)有什么作用?
【发布时间】:2019-09-19 21:13:03
【问题描述】:

在 python 文档 2.4.3. Formatted string literals 中,似乎可以在 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

【问题讨论】:

  • 看看这里:realpython.com/python-f-strings。他们为 python 支持字符串格式化的新方法提供了一个很好的列表。公平地说,我这辈子从来没有见过这种星号。也许这是新事物。希望对您有所帮助。

标签: python python-3.x string language-lawyer f-string


【解决方案1】:

f_expression 有两种替代方案:or_exprs 的逗号分隔列表,前面可选用星号,或单个 yield_expression。请注意,yield_expression 不允许使用星号。

我假设意图是仅在至少有一个逗号时才选择逗号分隔的列表替代方案,但语法实际上并没有这么说。我觉得最后的重复运算符应该是 + 而不是 *

所以f"{*1}" 将是一个语法错误,因为有一个星号,但没有逗号。 f"{*1,*2}" 在语法上是有效的,但是因为 1 和 2 是不可迭代的,所以会出现类型错误。 f"{*[1], *[2]}" 有效且作用与f"{1,2}" 相同。所以星号是允许的,因为它充当元组中的 splat 运算符,可以在 f 表达式中不带括号写入。

请注意,使用or_expr 作为* 的操作数并不意味着必须在其中使用按位或运算符 - 它只是意味着按位或运算符是优先级层次结构中的第一个运算符将被允许​​作为* 的操作数。所以这只是设置前缀* 与其他表达式的优先级。我相信or_expr 一直被用作操作数,在语法中的任何地方都使用前缀*(即前缀* 后跟一个表达式而不是参数名称的任何地方)。

【讨论】:

  • 是的,但它也允许(基于建议语法)非逗号分隔。此外,为什么要使用"*" or_expror_expr 链接到二进制位表达式?
  • @Kasrâmvd “是的,但它也允许(基于建议语法)非逗号分隔”它允许非逗号分隔的表达式(通过 yield_expression 替代),但它不允许在其中使用星号。仅当至少有一个逗号时才允许使用星号。
  • @Kasrâmvd 请注意,使用 or_expr 并不意味着必须在此处使用或运算符 - 它只是意味着按位或运算符是优先级层次结构中的第一个运算符允许作为* 的操作数。所以这只是设置前缀* 与中缀运算符的优先级。而且我相信他们始终使用or_expression 作为操作数,在语法中的任何地方都为* 加上前缀。
  • 这似乎回答了我的问题。我测试并确认f"{*l, *l}"f"{*l,}" 是有效的f-string,其中l = [1,2,3]f_expression 的定义并不完美,但可能是为了简单。
  • 解释or_expr 用于修复优先级层次结构中的* 的注释可以合并到答案中。这是造成混乱的主要原因(以及f"{*&lt;...&gt;}" 是否有意义,答案已经涵盖)。
猜你喜欢
  • 2021-09-21
相关资源
最近更新 更多