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

ал этоблог на новых струнах Python, и они кажутся действительно аккуратными. Тем не менее, я хочу иметь возможность загружать f-строку из строки или файла.

Я не могу найти какой-либо строковый метод или другую функцию, которая делает это.

Из примера в моей ссылке выше:

name = 'Fred'
age = 42
f"My name is {name} and I am {age} years old"

'My name is Fred and I am 42 years old'

Но что, если у меня была строкаs? Я хочу быть в состоянии эффективноs, что-то вроде этого:

name = 'Fred'
age = 42
s = "My name is {name} and I am {age} years old"
effify(s)

Оказывается, я уже могу выполнить что-то похожее наstr.format и набрать производительность. А именно:

format = lambda name, age: f"My name is {name} and I am {age} years old"
format('Ted', 12)

'My name is Ted and I am 12 years old'
 piRSquared16 нояб. 2017 г., 22:17
f-строки являются новыми в Python 3.6 и являются литералами, не подлежащими вызову. Я знаю, как получить то, что работает аналогично. Я хочу сделать существующую строку (возможно, загруженную из файла) и иметь форматированный строковый литерал.
 turbulencetoo16 нояб. 2017 г., 22:13
s.format(name="John", age=10) или жеs.format(**globals) или похожие.
 zipa16 нояб. 2017 г., 22:21
 coldspeed16 нояб. 2017 г., 22:21
IIUC, нет, к сожалению, если вы не используетеexec :( (по крайней мере, я так думаю)
 Christian Dean16 нояб. 2017 г., 22:19
Так что, если я вас правильно понял, вы спрашиваете, как вы можете контролировать, когда выражения в f-строках вычисляются, @piRSquared?

Ответы на вопрос(3)

Простым решением было бы использовать f-строки и eval.

def effify(non_f_str: str):
    return eval(f'f"""{non_f_str}"""')

name = 'Fred'
age = 42
s = "My name is {name} and I am {age} years old"
effify(s)
'My name is Fred and I am 42 years old'

Это в основном добавляет «f» к строке и затем оценивается как код. Тройные кавычки также помогают разместить многострочные строки. Функция будет пытаться вытащить переменные, на которые есть ссылка в f-строке, из области вокруг своего вызова. Как указано, используяeval потенциально может быть опасным, но если вы знаете свой источник, то я думаю, что он не более опасен, чем выполнение любого другого кода.

Решение Вопроса

строковый литерал - это код», но и опасным способом выполнения произвольного кода. Это допустимая f-строка:

f"{__import__('os').system('install ransomware or something')}"

и он будет выполнять произвольные команды оболочки при оценке.

Вы спрашиваете, как взять строку, загруженную из текстового файла, и оценить ее как код, а ответ сводится кeval, Это конечнориск безопасности а такженаверное плохая идея, поэтому я рекомендую не пытаться загружать f-строки из файлов.

Если вы хотите загрузить F-строкуf"My name is {name} and I am {age} years old" из файла, то на самом деле положить

f"My name is {name} and I am {age} years old"

в файле,f и кавычки и все.

Прочитайте его из файла, скомпилируйте и сохранитеeval не нужно каждый раз перекомпилировать):

compiled_fstring = compile(fstring_from_file, '<fstring_from_file>', 'eval')

и оцените это сeval:

formatted_output = eval(compiled_fstring)

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

 l4mpi27 авг. 2018 г., 15:17
Я не совсем понимаю, почему кто-то будет использовать compile и eval вместоstring_from_file.format(**locals()), Если ответ «потому что у f-строк могут быть более сложные выражения», написание небольшого DSL, который обрабатывает все необходимые выражения, предпочтительнее, чем использование eval и разрешение выполнения произвольного кода.

как-то так:

name = 'Fred'
age = 42
s = "My name is {name} and I am {age} years old"
effify(s)

AFAIU, в соответствии сPEP 498 - интерполяция буквенных строкэто невозможно1, Нет способа программно создать f-строку:

В исходном коде Python,f-строка - это буквальная строка с префиксом 'f', которая содержит выражения внутри фигурных скобок.

1Если, конечно, вы не захотите использовать что-то вродеexec как упомянуто @coldspeed. Но на этом этапе минусы, вероятно, перевешивают плюсы.

 piRSquared16 нояб. 2017 г., 22:54
Я возьму невозможное сейчас. Если это изменится в будущем, я обновлю этот пост.
 piRSquared01 дек. 2017 г., 19:01
@ChristianDean Я не принял, потому что я ожидаю принять другой ответ, как только я заставлю его работать. Еще раз спасибо за ответ.
 Christian Dean16 нояб. 2017 г., 22:25
@PatrickHaugh Ах, я понимаю, что ты имеешь в виду. Не могу понять, о чем он спрашивает. Я удалю свой ответ.
 Patrick Haugh16 нояб. 2017 г., 22:24
Я думаю, что он ищет какую-то функциюfoo такой, чтоfoo("{x}") возвращаетсяf"{x}"
 Christian Dean01 дек. 2017 г., 20:54
@piRSquared Эй, чувак, нет проблем. Я ценю, что ты дал мне знать. Если у вас все получится, возможно, вы можете опубликовать ответ здесь. Я уверен, что другие будут заинтересованы, в том числе и я :)

Ваш ответ на вопрос