Подтвердить что ты не робот

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

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

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

Или:

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

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

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

4b9b3361

Ответ 1

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

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

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

Ответ 2

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

Например:

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

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

Ответ 3

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

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

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

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

Я не был уверен, что это сработает, но он был счастлив. Что касается того, как это pythonic, я не уверен, что tbh.

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)

Ответ 4

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

func = 'my_func'

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

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

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

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

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

'{}'.format(my_func())