将字符串转换为 f-string

40

如何将经典字符串转换为f-字符串?

variable = 42
user_input = "The answer is {variable}"
print(user_input)

输出:答案是 {variable}

f_user_input = # Here the operation to go from a string to an f-string
print(f_user_input)

期望输出:答案是42

5个回答

68

f-string是一种语法,而不是对象类型。您无法将任意字符串转换为该语法,该语法创建字符串对象,而不是相反。

我假设您想使用user_input作为模板,因此只需在user_input对象上使用str.format()方法即可:

variable = 42
user_input = "The answer is {variable}"
formatted = user_input.format(variable=variable)

如果您想提供可配置的模板服务,请创建一个命名空间字典,其中包含可以插值的所有字段,并使用**kwargs调用语法和str.format()应用该命名空间。
namespace = {'foo': 42, 'bar': 'spam, spam, spam, ham and eggs'}
formatted = user_input.format(**namespace)

用户可以在命名空间中使用任何键来填充 {...} 字段(或不填,未使用的字段将被忽略)。

好的,我明白了。但这意味着我必须知道用户可以输入的所有值,而事实并非如此:输入将是一个SQL查询,我无法真正知道用户将输入什么:“select * from {table} where day = {day} and client = {client}”。你有没有在这种情况下有任何想法? - François M.
1
@fmalaussena:那么任意条目会给你什么值?您可以预先解析格式并查看使用了哪些字段名称,请参见Python字符串中的动态字段如何从格式()方法的字符串中获取变量名称 - Martijn Pieters
locals() 函数可以帮助将所有本地变量作为参数传递。formatted = user_input.format(**locals()) - Arjun Ariyil
@ArjunAriyil 从安全角度来看,这不是一个好主意,你想让最终用户访问所有本地变量吗? - Martijn Pieters
@MartijnPieters,是的,同意。这不是一种安全的方式。但第一个评论听起来像他想要实现的目标。只有在我们完全信任user_input来源时才能使用它。但我猜使用locals()比其他建议使用eval的答案更好。 - Arjun Ariyil
在Python中的一个奇怪之处是,如果你的字符串通过使用字典来调用值,你不能在键周围加引号。例如,如果你有a = {'b': 'hi'},你不能这样做"test {a['b']}".format(a=a),而应该这样做"test {a[b]}".format(a=a) - undefined

17

实际的答案可能是:不要这样做。将用户输入作为f-string处理,就像处理创建安全风险的代码一样。您必须非常确定您可以信任输入的来源。

如果你处于知道用户输入可以被信任的情况下,你可以使用eval()来做到这一点:

variable = 42
user_input="The answer is {variable}"
eval("f'{}'".format(user_input))
'The answer is 42'

编辑以添加:@wjandrea指出另一个答案进一步阐述了这一点。


2
这里有一个回答,进一步阐述了安全性方面的问题:https://dev59.com/olYN5IYBdhLWcg3wfoRj#47599254 - wjandrea
3
@Von 答案加一,因为它也允许处理内部表达式,例如 "答案是 {variable+1}",这会引发在普通字符串(非 f-strings)上调用 format 方法时出现的 KeyError 。然而,这种解决方案并不百分之百可靠,因为它假设字符串不包含简单引号,例如 user_input="The 'answer' is {variable}" 会引发 SyntaxError。以下是解决此问题的方法: eval(f"f{repr(user_input)}") - Pierre Denis

6
variable = 42
user_input = "The answer is {variable}"
# in order to get The answer is 42, we can follow this method
print (user_input.format(variable=variable))

(或者)

user_input_formatted = user_input.format(variable=variable)
print (user_input_formatted)

Good link https://cito.github.io/blog/f-strings/


6

只是为了补充一种类似的做法。 但是使用 str.format() 选项更加推荐。

variable = 42
user_input = "The answer is {variable}"
print(eval(f"f'{user_input}'"))

实现与Martijn Pieters上述提到的相同效果的更安全方法:

def dynamic_string(my_str, **kwargs):
    return my_str.format(**kwargs)

variable = 42
user_input = "The answer is {variable}"
print('1: ', dynamic_string(my_str=user_input, variable=variable))
print('2: ', dynamic_string(user_input, variable=42))

1:  The answer is 42
2:  The answer is 42

-7
你可以使用 f-string 而不是普通字符串。
variable = 42
user_input = f"The answer is {variable}"
print(user_input) 

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接