Python 对字符串使用locals()和format()方法:是否有任何警告?

Python 对字符串使用locals()和format()方法:是否有任何警告?,python,string-formatting,local-variables,locals,Python,String Formatting,Local Variables,Locals,使用以下模式是否存在任何缺点、警告或不良做法警告 def buildString(user, name = 'john', age=22): userId = user.getUserId() return "Name: {name}, age: {age}, userid:{userId}".format(**locals()) 我有一个非常重复的字符串生成代码要编写,我很想使用它,但是关于使用locals()的一些东西让我感到不舒服。在这种情况下是否存在意外行为的危险 编辑

使用以下模式是否存在任何缺点、警告或不良做法警告

def buildString(user, name = 'john', age=22):
    userId = user.getUserId()
    return "Name: {name}, age: {age}, userid:{userId}".format(**locals())
我有一个非常重复的字符串生成代码要编写,我很想使用它,但是关于使用
locals()
的一些东西让我感到不舒服。在这种情况下是否存在意外行为的危险

编辑:上下文

我发现自己一直在写这样的东西:

"{name} {age} {userId} {etc}...".format(name=name, age=age, userId=userId, etc=etc)

如果格式字符串不是用户提供的,则可以使用此用法

格式
优于使用旧的
%
替换字符串。
是Python内置的,其行为将是可靠的

我认为
本地人
正是你所需要的。
只是不要根据本地人修改字典,我会说你有一个很好的解决方案


如果格式字符串是用户提供的,那么您很容易受到各种不良的注入攻击。

从Python 3.6.0开始,现在有一种官方的方法可以做到这一点:

它的工作原理如下:

f'normal string text {local_variable_name}'
例如,代替这些:

"hello %(name) you are %(age) years old" % locals()
"hello {name} you are {age} years old".format(**locals())
"hello {name} you are {age} years old".format(name=name, age=age)
只要这样做:

f"hello {name} you are {age} years old"
以下是官方的例子:

>>> name = "Fred"
>>> f"He said his name is {name}."
'He said his name is Fred.'
>>> width = 10
>>> precision = 4
>>> value = decimal.Decimal("12.34567")
>>> f"result: {value:{width}.{precision}}"  # nested fields
'result:      12.35'
参考:

Python 3.6版之前的答案 这是非常古老的,但是如果您发现自己在使用
.format
我在传入
**locals
时遇到的一个警告是,如果您没有在任何地方定义该变量,它将崩溃。在大多数现代IDE中,明确说明传入的变量可以避免这种情况

foo = "bar"
"{foo} and {baz} are pair programming".format(**locals())
<exception occurs>
foo=“bar”
“{foo}和{baz}是成对编程”。格式(**locals())

我看不出它有什么可怕的问题……与字符串是否应该有一个警告,即该字符串永远不会由用户提供密切相关?这可能会打开对每个局部变量内容的访问。直击@BobStein VisiBone,我已经更新了我的答案。使用locals()而不仅仅是您需要的变量,似乎会产生非常小的性能开销,因为您有一个额外的函数调用,并且正在构建一个更大的字典。不过,对于大多数应用程序来说,这可能可以忽略不计:我在一个快速测试用例中看到了大约2%的差异。可以说它是内部生成的,而不是用户提供的,这将在这里应用,使用这个:f“{foo}和{baz}是成对编程”,您将得到一个名称错误。但在这种情况下,IDE可以检测到它。应避免使用原始解决方案。只要使用everywhere f-strings并强制使用Python 3.6+,您就可以免费获得asyncio的语法。@DeaD_EyE我想我发现了一个例子,.format仍然有用:如果变量是在字符串之后定义的,那么就可以格式化
s=“”{foo}不是{bar}”“;foo=“A”;bar=“B”;格式(**locals())