如何将字符串转换为 f 字符串?
How do I convert a string into an f-string?
我正在阅读 this blog post on Python's new f-strings,它们看起来真的很整洁。但是,我希望能够从字符串或文件中加载 f 字符串。
我似乎找不到执行此操作的任何字符串方法或其他函数。
来自博客中的示例post:
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
呢?我希望能够 eff-ify 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'
But what if I had a string s? I want to be able to eff-ify s, something like this:
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 字符串:
In Python source code, an f-string is a literal string, prefixed with 'f', which contains expressions inside braces.
1当然,除非你愿意使用像@coldspeed 提到的exec
这样的东西。但在这一点上,缺点可能大于优点。
f-strings 是代码。不仅以安全的 "of course a string literal is code" 方式,而且以危险的任意代码执行方式。这是一个有效的 f 字符串:
f"{__import__('os').system('install ransomware or something')}"
它会在评估时执行任意 shell 命令。
您问的是如何获取从文本文件加载的字符串并将其作为代码求值,答案归结为 eval
。这当然存在 安全风险 并且 可能是个坏主意 ,因此我建议不要尝试从文件加载 f 字符串。
如果你想从文件中加载 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-strings 的源。
一个简单的解决方案是使用 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
可能很危险,但如果您知道您的来源,那么我认为它并不比执行任何其他代码更危险。
我正在阅读 this blog post on Python's new f-strings,它们看起来真的很整洁。但是,我希望能够从字符串或文件中加载 f 字符串。
我似乎找不到执行此操作的任何字符串方法或其他函数。
来自博客中的示例post:
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
呢?我希望能够 eff-ify 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'
But what if I had a string s? I want to be able to eff-ify s, something like this:
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 字符串:
In Python source code, an f-string is a literal string, prefixed with 'f', which contains expressions inside braces.
1当然,除非你愿意使用像@coldspeed 提到的exec
这样的东西。但在这一点上,缺点可能大于优点。
f-strings 是代码。不仅以安全的 "of course a string literal is code" 方式,而且以危险的任意代码执行方式。这是一个有效的 f 字符串:
f"{__import__('os').system('install ransomware or something')}"
它会在评估时执行任意 shell 命令。
您问的是如何获取从文本文件加载的字符串并将其作为代码求值,答案归结为 eval
。这当然存在 安全风险 并且 可能是个坏主意 ,因此我建议不要尝试从文件加载 f 字符串。
如果你想从文件中加载 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-strings 的源。
一个简单的解决方案是使用 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
可能很危险,但如果您知道您的来源,那么我认为它并不比执行任何其他代码更危险。