【发布时间】:2018-05-31 20:53:10
【问题描述】:
我正在使用模板字符串来生成一些文件,我喜欢新的 f 字符串的简洁性,用于减少我以前的模板代码,如下所示:
template_a = "The current name is {name}"
names = ["foo", "bar"]
for name in names:
print (template_a.format(**locals()))
现在我可以这样做了,直接替换变量:
names = ["foo", "bar"]
for name in names:
print (f"The current name is {name}")
但是,有时将模板定义在别处是有意义的——在代码的更高层,或者从文件或其他东西中导入。这意味着模板是一个带有格式化标签的静态字符串。字符串必须发生一些事情才能告诉解释器将字符串解释为新的 f 字符串,但我不知道是否有这样的事情。
有什么方法可以引入字符串并将其解释为 f 字符串以避免使用 .format(**locals()) 调用?
理想情况下,我希望能够像这样编写代码...(magic_fstring_function 是我不理解的部分所在):
template_a = f"The current name is {name}"
# OR [Ideal2] template_a = magic_fstring_function(open('template.txt').read())
names = ["foo", "bar"]
for name in names:
print (template_a)
...具有所需的输出(无需两次读取文件):
The current name is foo
The current name is bar
...但我得到的实际输出是:
The current name is {name}
The current name is {name}
【问题讨论】:
-
你不能用
f字符串来做到这一点。f字符串不是数据,当然也不是字符串;这是代码。 (使用dis模块检查。)如果您希望稍后评估代码,请使用函数。 -
仅供参考,PEP 501 提出了一个接近您的第一个理想的功能,但目前“推迟了 [f-strings] 的进一步体验。”
-
模板是静态字符串,但 f 字符串不是字符串,而是代码对象,正如 @kindall 所说。我认为 f 字符串在实例化时(在 Python 3.6,7 中)会立即与变量绑定,而不是在最终使用时绑定。所以 f-string 可能不如你丑陋的旧
.format(**locals())有用,尽管在外观上更好。在 PEP-501 实施之前。 -
Guido 救了我们,但是PEP 498 really botched it。 PEP 501 描述的延迟评估绝对应该被纳入核心 f-string 实现。现在,我们在功能较少、速度极慢的
str.format()方法(一方面支持延迟评估)和功能更强大、速度极快的 f 字符串语法 not 支持延迟评估之间犹豫不决。所以我们仍然需要两者,Python 仍然没有标准的字符串格式化程序。 插入 xkcd 标准模因。
标签: python python-3.x string-interpolation python-3.6 f-string