为什么`str.format()`忽略其他/未使用的参数?

时间:2016-07-13 11:02:08

标签: python string python-3.x string-formatting

我看到"Why doesn't join() automatically convert its arguments to strings?"the accepted answer让我思考:自

  

明确比隐含更好。

  

错误绝不应该以无声方式传递。

为什么str.format()会忽略其他/未使用(有时会意外传递)的参数?对我而言,它看起来像是一个无声地传递的错误,它肯定不是明确的:

>>> 'abc'.format(21, 3, 'abc', object(), x=5, y=[1, 2, 3])
'abc'

这实际上导致我的朋友发现os.makedirs(path, exist_ok=True)仍出现错误的问题,即使the docs for os.makedirs()表示exist_ok=True即使path已存在也不会引发错误。 事实证明他只有一个很长的行与嵌套函数调用,而exist_ok被传递到嵌套.format()调用而不是os.makedirs()

1 个答案:

答案 0 :(得分:12)

忽略未使用的参数可以为任意大小的字典或对象创建任意格式字符串。

假设您希望为程序提供让最终用户更改输出的功能。您记录了哪些字段可用,并告诉用户将这些字段放在字符串中的{...}个插槽中。然后,最终用户可以使用正在使用的任何数量的字段创建模板字符串,包括根本不包含

换句话说,选择是慎重的,因为允许更多参数而不是转换的实际原因。请注意,出于同样的原因,启发Python PEP的C#String.Formatter实现也是如此。

并非PEP这一部分的讨论是明确的; Guido van Rossum在某些时候tries to address this issue

  

如果太少或太少,PEP会对发生的事情保持沉默   许多位置参数,或者是否存在丢失或未使用的关键字。   遗失的应该是错误;我不确定冗余(未使用)   那些。一方面抱怨这些让我们更加确定   格式字符串是正确的。另一方面有一些   用于传递大量关键字参数的用例(例如简单的网络   模板可以使用** dict传递一组固定的变量。即使在   i18n(翻译)应用我可以看到允许未使用的有用性   参数

PEP作者responded在这一点上仍未决定。

对于必须为未使用的参数引发异常的用例,您应该将string.Formatter() class子类化,并为Formatter.check_unused_args()提供实现;默认实现什么都不做。这当然对您使用str.format(*args, **kwargs)而不是Formatter().format(str, *args, **kwargs)的朋友有帮助。我相信在某些方面的想法是你可以用自定义实现替换str.format()使用的格式化程序,但这种情况从未发生过。

如果您使用flake8 linter,那么您可以添加flake8-string-format plugin来检测明显的情况,您传入的显式关键字参数未被格式字符串。

相关问题