Python 中的格式化字符串和命名参数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17895835/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 09:25:28  来源:igfitidea点击:

format strings and named arguments in Python

pythonstringargumentsstring-formatting

提问by bkmagnetron

Case 1:

情况1:

"{arg1} {arg2}".format (10, 20)

It will give KeyError: 'arg1'because I didn't pass the named arguments.

它会给出,KeyError: 'arg1'因为我没有传递命名参数。

Case 2:

案例2:

"{arg1} {arg2}".format(arg1 = 10, arg2 = 20)

Now it will work properly because I passed the named arguments. And it prints '10 20'

现在它将正常工作,因为我传递了命名参数。它打印'10 20'

Case 3:

案例3:

And, If I pass wrong name it will show KeyError: 'arg1'

而且,如果我传递错误的名字,它会显示 KeyError: 'arg1'

 "{arg1} {arg2}".format(wrong = 10, arg2 = 20)

But,

但,

Case 4:

案例4:

If I pass the named arguments in wrong order

如果我以错误的顺序传递命名参数

"{arg1} {arg2}".format(arg2 = 10, arg1 = 20)

It works...

有用...

and it prints '20 10'

它打印 '20 10'

My question is why it works and what's the use of named argumentsin this case.

我的问题是它为什么有效以及在这种情况下命名参数的用途是什么。

采纳答案by Martijn Pieters

Named replacement fields (the {...}parts in a format string) match against keyword argumentsto the .format()method, and not positional arguments.

命名替换字段({...}在零件格式字符串针对匹配)的关键字参数.format()方法,而不是定位参数

Keyword arguments are like keys in a dictionary; order doesn't matter, as they are matched against a name.

关键字参数就像字典中的键;顺序无关紧要,因为它们与name匹配。

If you wanted to match against positionalarguments, use numbers:

如果您想匹配位置参数,请使用数字:

"{0} {1}".format(10, 20)

In Python 2.7 and up, you can omit the numbers; the {}replacement fields are then auto-numbered in order of appearance in the formatting string:

在 Python 2.7 及更高版本中,您可以省略数字;在{}替换字段,然后自动编号在外观上格式化字符串中的顺序:

"{} {}".format(10, 20) 

The formatting string can match against both positional andkeyword arguments, and can use arguments multiple times:

格式化字符串可以匹配位置参数关键字参数,并且可以多次使用参数:

"{1} {ham} {0} {foo} {1}".format(10, 20, foo='bar', ham='spam')

Quoting from the format string specification:

引用格式字符串规范

The field_nameitself begins with an arg_namethat is either a number or a keyword. If it's a number, it refers to a positional argument, and if it's a keyword, it refers to a named keyword argument.

所述FIELD_NAME本身开始于arg_name要么是数字或关键字。如果是数字,则表示位置参数,如果是关键字,则表示命名关键字参数。

Emphasis mine.

强调我的。

If you are creating a large formatting string, it is often much more readable and maintainable to use named replacement fields, so you don't have to keep counting out the arguments and figure out what argument goes where into the resulting string.

如果您正在创建一个大型格式化字符串,使用命名替换字段通常更具可读性和可维护性,因此您不必一直计算参数并找出哪个参数进入结果字符串的位置。

You can also use the **keywordscalling syntax to apply an existing dictionary to a format, making it easy to turn a CSV file into formatted output:

您还可以使用**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)

Here, picture, link, descriptionand priceare all keys in the rowdictionary, and it is much easierto see what happens when I apply the rowto the formatting string.

这里, picture, link,descriptionprice都是row字典中的键,当我将 应用于格式化字符串时,更容易看到会发生什么row

回答by Koen G.

Added benefits include

增加的好处包括

  • You don't have to worry about the order of the arguments. They will fall in the right place in the strings as indicated by there names in the formatter.
  • You can put the same argument in a string twice, without having to repeat the argument. E.g. "{foo} {foo}".format(foo="bar")gives 'bar bar'
  • 不必担心参数的顺序。它们将落在字符串中的正确位置,如格式化程序中的名称所示。
  • 您可以将相同的参数放入字符串两次,而不必重复该参数。例如"{foo} {foo}".format(foo="bar")给出 'bar bar'

Note that you can give extra arguments without causing errors as well. All this is especially useful when

请注意,您也可以提供额外的参数而不会导致错误。所有这些在以下情况下特别有用

  • you change the string formatter later on with less changes and thus smaller posibility for mistakes. If it does not contain new named arguments, the format function will still work without changing the arguments and put the arguments where you indicate them in the formatter.
  • you can have multiple formatter strings sharing a set of arguments. In these case you could for instance have a dictionary with the all arguments and then pick them out in the formatter as you need them.
  • 您稍后更改字符串格式化程序,更改较少,因此出错的可能性较小。如果它不包含新命名的参数,格式函数仍然可以在不更改参数的情况下工作,并将参数放在格式化程序中指示它们的位置。
  • 您可以让多个格式化字符串共享一组参数。在这些情况下,例如,您可以拥有一个包含所有参数的字典,然后根据需要在格式化程序中选择它们。

E.g.:

例如:

>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)