在 Python 中格式化字符串和命名参数
Posted
技术标签:
【中文标题】在 Python 中格式化字符串和命名参数【英文标题】:format strings and named arguments in Python 【发布时间】:2013-07-27 13:52:46 【问题描述】:案例 1:
"arg1 arg2".format(10, 20)
它会给出KeyError: 'arg1'
,因为我没有传递命名参数。
案例 2:
"arg1 arg2".format(arg1=10, arg2=20)
现在它可以正常工作了,因为我传递了命名参数。
它打印'10 20'
案例 3:
而且,如果我传递了错误的名称,它将显示KeyError: 'arg1'
"arg1 arg2".format(wrong=10, arg2=20)
但是,
案例 4:
如果我以错误的顺序
传递命名参数"arg1 arg2".format(arg2=10, arg1=20)
它有效...
它打印'20 10'
我的问题是它为什么会起作用以及在这种情况下命名参数有什么用。
【问题讨论】:
我认为它们只是为了便于阅读。 因为它是通过名称而不是位置来查找的...您认为命名参数是什么意思? 看起来您只是将 arg2 重命名为 arg1,反之亦然。换句话说,arg1 现在是 20 而不是 10,这就是为什么您会看到字符串中的第一个数字打印 20 而不是 10。要进行所需的测试,您只需将 args 及其值移动到新位置format() 调用,它会按照您期望的方式运行。这里没有什么不寻常的。 【参考方案1】:命名替换字段(format string 中的 ...
部分)匹配 关键字参数 到 .format()
方法,而不是 位置参数。 p>
关键字参数就像字典中的键;顺序无关紧要,因为它们与 name 匹配。
如果您想匹配 位置 参数,请使用数字:
"0 1".format(10, 20)
在 Python 2.7 及更高版本中,您可以省略数字;然后, 替换字段会按照在格式化字符串中出现的顺序自动编号:
" ".format(10, 20)
格式化字符串可以匹配位置和关键字参数,并且可以多次使用参数:
"1 ham 0 foo 1".format(10, 20, foo='bar', ham='spam')
引用format string specification:
field_name 本身以 arg_name 开头,它可以是数字或关键字。如果是数字,则引用位置参数,如果是关键字,则引用命名关键字参数。
强调我的。
如果您正在创建一个大格式字符串,使用命名替换字段通常更具可读性和可维护性,因此您不必一直计算参数并找出结果字符串中的哪个参数。
您还可以使用**keywords
调用语法将现有字典应用于格式,从而轻松将 CSV 文件转换为格式化输出:
import csv
fields = ('category', 'code', 'price', 'description', 'link', 'picture', 'plans')
table_row = '''\
<tr>
<td><img src="picture"></td>
<td><a href="link">description</a> (price:.2f)</td>
</tr>
'''
with open(filename, 'rb') as infile:
reader = csv.DictReader(infile, fieldnames=fields, delimiter='\t')
for row in reader:
row['price'] = float(row['price']) # needed to make `.2f` formatting work
print table_row.format(**row)
这里,picture
、link
、description
和 price
都是 row
字典中的键,当我应用row
到格式化字符串。
【讨论】:
它不仅更具可读性,在使用自然语言和“国际化”(i18n) 时也非常有用,有时您希望格式化消息的特定部分以不同的顺序以不同的语言出现. @torek:我什至不打算讨论模板中的不同排序;关键是每个插槽都指向一个特定的参数。您也可以在模板中以不同的顺序放置位置参数。【参考方案2】:额外的好处包括
您不必担心参数的顺序。它们将位于字符串中的正确位置,如格式化程序中它们的名称所示。 您可以将同一个参数放在一个字符串中两次,而不必重复该参数。例如。"foo foo".format(foo="bar")
给出“酒吧酒吧”
请注意,您也可以提供额外的参数而不会导致错误。 当
您稍后会更改字符串格式化程序,更改较少,因此出错的可能性较小。如果它不包含新的命名参数,格式化函数仍然可以在不更改参数的情况下工作,并将参数放在您在格式化程序中指定的位置。 您可以让多个格式化字符串共享一组参数。在这种情况下,您可以拥有一个包含所有参数的字典,然后根据需要在格式化程序中挑选它们。例如:
>d = "foo":"bar", "test":"case", "dead":"beef"
>print("I need foo (foo) and dead (dead)".format(**d))
>print("I need test (test) and foo (foo) and then test again (test)".format(**d))
I need foo (bar) and dead (beef)
I need test (case) and foo (bar) and then test again (case)
【讨论】:
最后一个例子是我见过的 Python 中模板化字符串编码最方便的方法之一。特别是我不知道可以将字典参数传递给format
,其中并非所有键都实际出现在格式字符串中。感谢您指出这一点!以上是关于在 Python 中格式化字符串和命名参数的主要内容,如果未能解决你的问题,请参考以下文章