为什么我必须在str.format中的列表前面使用*(* args,** kwargs)

时间:2016-03-17 10:50:25

标签: python string format variadic-functions

阅读完这些内容后:
Special use of args / kwargs
https://www.python.org/dev/peps/pep-3102/
What does ** (double star) and * (star) do for parameters?
https://docs.python.org/3.5/library/string.html#formatstrings

我想确定我理解得很好:str.format(*args, **kwargs)

如果uniques是两个整数的列表,例如[0, 0],我将在一个循环中使用它,其中一个条件用于递增第一个元素而没有条件来递增第二个元素,其中:

 print('Task finished. {0!s} retrieved out of {1!s} tested'.format(*uniques))

我必须使用*uniques,因为uniques将作为格式传递给格式。但如果我使用

 print('Task finished. {0.[0]} retrieved out of {0.[1]} tested'.format(uniques))

它引发了价值错误:ValueError: Empty attribute in format string。在uniques周围使用括号无济于事。我真的不明白为什么?请有人澄清一下吗?

在第一种情况下,列表是解压缩然后转换为元组,而在第二种情况下,不是因为列表不能像格式一样立即转换为元组,就像format(uniques[0], uniques[1])一样将?如果我是对的,为什么会这样,因为有tuple(list)函数可以做到这一点,所以,这很简单?

2 个答案:

答案 0 :(得分:4)

您正在混合属性订阅语法。 0.[0]告诉格式查找名称为[0]属性。但是,formal grammar只允许valid identifier跟随点(意思是由字母,数字和下划线组成的单词,以字母或下划线开头),而[0]不会&#39} ; t匹配该规则,因此您得到一个根本没有属性名称的错误。

放下点:

print('Task finished. {0[0]} retrieved out of {0[1]} tested'.format(uniques))

这现在有效,因为现在格式解析器正确地看到了订阅:

>>> uniques = [0, 0]
>>> print('Task finished. {0[0]} retrieved out of {0[1]} tested'.format(uniques))
Task finished. 0 retrieved out of 0 tested
>>> uniques = [42, 81]
>>> print('Task finished. {0[0]} retrieved out of {0[1]} tested'.format(uniques))
Task finished. 42 retrieved out of 81 tested

0[0]说明符告诉str.format解析器使用第一个位置参数(此处由uniques提供),然后通过订阅[0]将其作为序列进行威胁,所以第一个元素。

使用'...'.format(*uniques)时,任何 iterable 都可以,无论是列表还是元组或不同类型的可迭代(包括生成器); Python迭代它以产生单独的参数。对于[42, 81],这意味着Python将调用该方法,就像您以'...'.format(42, 81)方式调用它一样。在字符串格式中,您必须使用{0}{1}来处理这些单独的参数。

答案 1 :(得分:1)

您的格式字符串中有拼写错误:

print('Task finished. {0[0]} retrieved out of {0[1]} tested'.format(uniques))