piR*_*red 21 python python-3.6 f-string
我正在阅读关于python的新f字符串的博客,它们看起来非常整洁.但是,我希望能够从字符串或文件加载f-string.
我似乎找不到任何字符串方法或其他功能.
从上面链接中的示例:
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'
Run Code Online (Sandbox Code Playgroud)
但是,如果我有一个字符串s怎么办?我希望能够有效s,这样的事情:
name = 'Fred'
age = 42
s = "My name is {name} and I am {age} years old"
effify(s)
Run Code Online (Sandbox Code Playgroud)
事实证明,我已经可以执行类似的操作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'
Run Code Online (Sandbox Code Playgroud)
use*_*ica 16
f-strings是代码.不只是在安全中,"当然是字符串文字是代码"的方式,而是以危险的,任意代码执行的方式.这是一个有效的f字符串:
f"{__import__('os').system('install ransomware or something')}"
Run Code Online (Sandbox Code Playgroud)
并且在评估时它将执行任意shell命令.
你问的是如何从文本文件中加载一个字符串并将其作为代码进行评估,答案归结为eval.这当然是一个安全风险,可能是一个坏主意,所以我建议不要尝试从文件加载f-strings.
如果f"My name is {name} and I am {age} years old"要从文件加载f-string ,则实际放入
f"My name is {name} and I am {age} years old"
Run Code Online (Sandbox Code Playgroud)
在文件中,f引号和所有.
从文件中读取它,编译并保存(因此eval不必每次都重新编译它):
compiled_fstring = compile(fstring_from_file, '<fstring_from_file>', 'eval')
Run Code Online (Sandbox Code Playgroud)
并评估它eval:
formatted_output = eval(compiled_fstring)
Run Code Online (Sandbox Code Playgroud)
如果你这样做,要非常小心你加载你的f字符串的来源.
一个简单的解决方案是使用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'
Run Code Online (Sandbox Code Playgroud)
基本上,这会在字符串前加上“ f”,然后作为代码求值。三重引号也有助于容纳多行字符串。该函数将尝试从调用周围的作用域中提取f字符串中引用的变量。如前所述,使用eval可能有潜在的危险,但是如果您知道您的来源,那么我认为这并不比执行任何其他代码更危险。
但是,如果我有一个字符串s怎么办?我希望能够对s进行有效处理,例如:
Run Code Online (Sandbox Code Playgroud)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之类的东西。但是到那时,利弊可能超过利弊。