嵌套的f字符串

ale*_*cxe 44 python string-formatting python-3.x python-3.6 f-string

感谢David Beazley的推文,我最近发现新的Python 3.6 f字符串也可以嵌套:

>>> price = 478.23
>>> f"{f'${price:0.2f}':*>20s}"
'*************$478.23'
Run Code Online (Sandbox Code Playgroud)

要么:

>>> x = 42
>>> f'''-{f"""*{f"+{f'.{x}.'}+"}*"""}-'''
'-*+.42.+*-'
Run Code Online (Sandbox Code Playgroud)

虽然我很惊讶这是可能的,但我很遗憾这是多么实际,何时嵌套f字符串是有用的?这可以涵盖哪些用例?

注意:PEP本身没有提到嵌套f字符串,但是有一个特定的测试用例.

Jim*_*ard 47

我不认为格式化的字符串文字允许嵌套(通过嵌套,我认为是f'{f".."}')是仔细考虑可能的用例的结果,我更确信它只是允许它们符合他们的规范.

规范声明它们支持括号内的完整Python 表达式.它还声明格式化的字符串文字实际上只是一个在运行时计算的表达式(参见此处此处).因此,只允许将格式化的字符串文字作为另一个格式化字符串文字中的表达式才有意义,禁止它将否定对Python表达式的完全支持.

您无法找到文档中提到的用例(并且只在测试套件中查找测试用例)这一事实是因为这可能是实现的一个很好的(副作用)效果,而不是它激励用例.

  • 恐怕你是对的,完全同意。今天没有投票-明天回来。谢谢。 (2认同)

Eug*_*sky 9

我想这是为了在同一行中传递格式化参数,从而简化了f字符串的使用.

例如:

>>> import decimal
>>> width = 10
>>> precision = 4
>>> value = decimal.Decimal("12.34567")
>>> f"result: {value:{width}.{precision}}"
'result:      12.35'
Run Code Online (Sandbox Code Playgroud)

当然,它允许程序员编写绝对不可读的代码,但这不是目的:)

  • 是! `str.format`总是支持这个例如`'{0:.{1} f}'.format(math.pi,4)````3.1416'`.如果f-string不能支持那个,那么它就是蹩脚的. (2认同)
  • 您的示例不显示嵌套的 f 字符串,仅显示嵌套的大括号。 (2认同)

小智 9

任何基本用例都需要一个字符串来完整描述要放入 f 字符串大括号内的对象{}。例如,您需要字符串来索引字典。

因此,我最终在 ML 项目中使用了它,代码如下:

scores = dict()
scores[f'{task}_accuracy'] = 100. * n_valid / n_total
print(f'{task}_accuracy: {scores[f"{task}_accuracy"]}')
Run Code Online (Sandbox Code Playgroud)


小智 6

我用它来格式化货币。给定值如下:

a=1.23
b=45.67
Run Code Online (Sandbox Code Playgroud)

使用前导 $ 并对齐小数来格式化它们。例如

 $1.23
$45.67
Run Code Online (Sandbox Code Playgroud)

使用单个 f 字符串进行格式化,f"${value:5.2f}"您可以获得:

$ 1.23
$45.67
Run Code Online (Sandbox Code Playgroud)

有时这很好,但并非总是如此。嵌套的 f 字符串f"{f'${value:.2f}':>6}"为您提供确切的格式:

 $1.23
$45.67
Run Code Online (Sandbox Code Playgroud)

当您想要向数字添加其他单位符号(例如 )时,它同样有用#


and*_*894 5

我实际上只是遇到了类似的事情(我认为),并认为我会分享。

我的具体情况是一个大的肮脏的sql语句,在这里我需要有条件地具有一些非常不同的值,但有些fstrings是相同的(并且在其他地方也使用了)。

这是我的意思的简单示例。我选择的列都是相同的(无论是否也用于其他查询),但表名取决于组,并不是这样,我只能循环执行。

mycols=mycols当我有多个这样的参数时,每次都必须包含在str2中感觉有点脏。

我不确定这是否行得通,但很高兴能做到。至于它的pythonic程度,我不太确定。

mycols='col_a,col_b'

str1 = "select {mycols} from {mytable} where group='{mygroup}'".format(mycols=mycols,mytable='{mytable}',mygroup='{mygroup}')

group = 'group_b'

if group == 'group_a':
    str2 = str1.format(mytable='tbl1',mygroup=group)
elif group == 'group_b':
    str2 = str1.format(mytable='a_very_different_table_name',mygroup=group)

print(str2)
Run Code Online (Sandbox Code Playgroud)

  • 您可以在字符串文字中使用“{{my_table}}”,而不是在第 3 行的“format”中用“{{my_table}”替换“my_table”。然后“格式”将双大括号转换为单大括号。所以你会有更短的代码: `str1 = "select {mycols} from {{mytable}} where group='{{mygroup}}'".format(mycols=mycols)` (2认同)

小智 5

我发现嵌套在进行三元运算时很有用。你对可读性的看法会有所不同,但我发现这句话非常有用。

logger.info(f"No program name in subgroups file. Using {f'{prg_num} {prg_orig_date}' if not prg_name else prg_name}")
Run Code Online (Sandbox Code Playgroud)

因此,我的嵌套测试是:

  • 值是否被重用?(用于表达式重用的变量)
  • 表述清楚吗?(不超过复杂性)