如何将f-string与变量一起使用,而不是与字符串文字一起使用?

2024-04-18 19:37:10 发布

您现在位置:Python中文网/ 问答频道 /正文

我想将f-string与我的字符串变量一起使用,而不是与用字符串文本"..."定义的字符串一起使用。

这是我的密码

name=["deep","mahesh","nirbhay"]
user_input = r"certi_{element}" # this string i ask from user  

for element in name:
    print(f"{user_input}")

此代码提供输出:

certi_{element}
certi_{element}
certi_{element}

但我想:

certi_{deep}
certi_{mahesh}
certi_{nirbhay}

我该怎么做?


Tags: 字符串name文本密码inputstring定义element
3条回答

如果您定义:

def fstr(template):
    return eval(f"f'{template}'")

然后你可以:

name=["deep","mahesh","nirbhay"]
user_input = r"certi_{element}" # this string i ask from user  

for element in name:
    print(fstr(user_input))

作为输出:

certi_deep
certi_mahesh
certi_nirbhay

但请注意,用户可以在模板中使用表达式,例如:

import os  # assume you have used os somewhere
user_input = r"certi_{os.environ}"

for element in name:
    print(fstr(user_input))

你绝对不想要这个!

因此,更安全的选择是定义:

def fstr(template, **kwargs):
    return eval(f"f'{template}'", kwargs)

不再可能使用任意代码,但用户仍然可以使用字符串表达式,如:

user_input = r"certi_{element.upper()*2}"

for element in name:
    print(fstr(user_input, element=element))

作为输出:

certi_DEEPDEEP
certi_MAHESHMAHESH
certi_NIRBHAYNIRBHAY

这在某些情况下可能是需要的。

如果您希望用户能够访问您的命名空间,您可以这样做,但后果完全取决于您。不用f字符串,您可以使用^{}方法动态插值,语法非常相似。

如果希望用户只访问少量特定变量,可以执行以下操作

name=["deep", "mahesh", "nirbhay"]
user_input = "certi_{element}" # this string i ask from user  

for element in name:
    my_str = user_input.format(element=element)
    print(f"{my_str}")

当然,您可以将用户输入的密钥重命名为您使用的变量名:

my_str = user_input.format(element=some_other_variable)

你可以让用户访问你的整个名称空间(或者至少大部分名称空间)。请不要这样做,但请注意您可以:

my_str = user_input.format(**locals(), **globals())

我使用print(f'{my_str}')而不是print(my_str)的原因是为了避免将文本大括号视为进一步的错误扩展。例如,user_input = 'certi_{{{element}}}'

f"..."在将表达式结果插入文本时,字符串是很好的,但是没有文本,在单独的变量中有模板字符串。

可以使用^{}将值应用于该模板:

name=["deep","mahesh","nirbhay"]
user_input = "certi_{element}" # this string i ask from user  

for value in name:
    print(user_input.format(element=value))

使用名称(例如{element})的字符串格式占位符不是变量。而是为str.format()调用的关键字参数中的每个名称分配一个值。在上面的例子中,element=value传递value变量的值,用element填充占位符。

f-字符串不同,{...}占位符是而不是表达式,不能在模板中使用任意Python表达式。这是件好事,您不希望最终用户能够在您的程序中执行任意Python代码。有关详细信息,请参见Format String Syntax documenation

您可以传入任意数量的名称;字符串模板没有可以使用其中任何名称。如果将str.format()**mapping调用约定结合起来,则可以使用任何字典作为值的源:

template_values = {
    'name': 'Ford Prefect',
    'number': 42,
    'company': 'Sirius Cybernetics Corporation',
    'element': 'Improbability Drive',
}

print(user_input.format(**template_values)

上面将允许用户在模板中使用template_values中的任何名称,可以任意次数使用。

虽然可以使用locals()globals()生成将变量名映射到值的字典,但我不建议使用这种方法。使用像上面这样的专用名称空间来限制可用的名称,并为最终用户记录这些名称。

相关问题 更多 >