我正在阅读这篇关于python的新f字符串的blog,它们看起来非常整洁。但是,我希望能够从字符串或文件加载f-string。
我似乎无法找到执行此操作的任何字符串方法或其他功能。
从上面链接中的示例:
df$index[do.call(pmax, Map(function(x, y) l[[x]] + l[[y]],
head(seq_along(l), -1), tail(seq_along(l), -1))) > 1]
但是如果我有一个字符串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
答案 0 :(得分:11)
f-strings是代码。不只是在保险箱中,"当然,字符串文字是代码"方式,但是以危险的,任意代码执行的方式。这是一个有效的f字符串:
f"{__import__('os').system('install ransomware or something')}"
并且在评估时它将执行任意shell命令。
您正在询问如何从文本文件中加载字符串并将其评估为代码,答案归结为eval
。这当然是安全风险和可能是一个坏主意,所以我建议不要尝试从文件加载f-strings。
如果要从文件加载f-string 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字符串的来源。
答案 1 :(得分:4)
一个简单的解决方案是使用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
可能会很危险,但是如果您知道您的来源,那么我认为这并不比执行任何其他代码更危险。
答案 2 :(得分:3)
但是,如果我有一个字符串s怎么办?我希望能够得到像这样的东西:
name = 'Fred' age = 42 s = "My name is {name} and I am {age} years old" effify(s)
AFAIU,根据PEP 498 -- Literal String Interpolation,这不可能 1 。没有办法以编程方式创建一个f字符串:
在Python源代码中, f字符串是一个文字字符串,前缀为&#39; f&#39;,其中包含大括号内的表达式 。
1 除非您当然愿意使用exec
之类的内容作为@coldspeed提及。但在那时,缺点可能超过专业人士。