Вложенные f-строки

спасибо твит Дэвида Бизли, Я недавно узнал, что новый Python 3.6 f-strings также может быть вложенным:

>>> price = 478.23
>>> f"{f'${price:0.2f}':*>20s}"
'*************8.23'

или:

>>> x = 42
>>> f'''-{f"""*{f"+{f'.{x}.'}+"}*"""}-'''
'-*+.42.+*-'

хотя я удивлен, что это возможно, мне не хватает того, насколько это практично, когда было бы полезно вложить f-строки? Какие случаи использования может охватывать это?

Примечание: сам PEP не упоминает вложенные f-строки, но есть конкретного теста дело.

4 ответов


Я не думаю, что форматированные строковые литералы позволяют вложенность (по вложенности, я понимаю, что это означает f'{f".."}') является результатом тщательного рассмотрения возможных случаев использования, я более убежден, что это просто разрешено, чтобы они соответствовали их спецификации.

в спецификации указано, что они поддержка полного Python выражения внутри скобок. Также указано, что форматированный строковый литерал на самом деле это просто выражение это оценивается во время выполнения (см. здесь и здесь). В результате имеет смысл разрешить форматированный строковый литерал как выражение внутри другого форматированного строкового литерала, запрещая это отрицает полную поддержку выражений Python.

тот факт, что вы не можете найти варианты использования, упомянутые в документах (и только найти тестовые случаи в наборе тестов), потому что это, вероятно, хороший (побочный) эффект реализации, а не мотивирует вариант использования.


Я думаю, это передать параметры форматирования в одной строке и, таким образом, упростить f-strings использование.

например:

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

конечно, это позволяет программистам писать абсолютно нечитаемый код, но это не цель :)


Я на самом деле только что наткнулся на что-то подобное (я думаю) и подумал, что поделюсь.

мой конкретный случай - большой грязный оператор sql, где мне нужно условно иметь некоторые очень разные значения, но некоторые fstrings одинаковы (а также используются в других местах).

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

включения mycols=mycols в str2 каждый раз чувствовал себя немного грязным, когда у меня есть несколько таких параметров.

Я не был уверен, что это сработает, но был рад, что это так. Что касается того, как это происходит, я не совсем уверен.

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)

вы можете использовать его для dynamicism. Например, предположим, что у вас есть переменная с именем некоторой функции:

func = 'my_func'

тогда вы могли бы написать:

f"{f'{func}'()}" 

что было бы эквивалентно:

'{}'.format(locals()[func]()) 

или, что то же самое:

'{}'.format(my_func())