为什么 Python 字符串格式会默默地忽略 class 实例中不匹配的参数计数?
Why does Python string formatting silently ignore mismatched argument counts with class instances?
通常,如果字符串中的占位符数量与传递的参数数量不匹配,Python 旧式字符串格式会报错:
>>> 'no.placeholders.here' % 'test'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: not all arguments converted during string formatting
但是,当传递的参数是用户定义的实例时 class,它会默默地忽略它:
>>> class Test(object): pass
>>> 'no.placeholders.here' % Test()
'no.placeholders.here'
这种行为似乎不一致,并导致了一些难以追踪的错误。为什么格式参数的类型对于此错误很重要?
这正是 %
格式 旧
的原因
%
格式 众所周知 因为它在参数处理方面的不一致导致异常与否取决于类型。只有两种方法可以使用 %
格式并避免不一致:
- 确保格式字符串包含正好一个格式字段并将对象传递给格式作为唯一正确的参数
- 使用
tuple
或 dict
作为正确的参数。不要使用 list
s、set
s 或 Model
s。 仅 tuple
和 dicts
。
这些取自 documentation
If format requires a single argument, values may be a single non-tuple
object. Otherwise, values must be a tuple with exactly the number
of items specified by the format string, or a single mapping object
(for example, a dictionary).
您的示例不属于这两种情况,因为您有 0 个格式字段,这与 1 不同,因此正确的参数 必须 是 tuple
或映射,但您传递的是字符串和用户定义的对象。因此,您处于 "undefined behaviour".
之下
this 问题(在我的回答中)已经讨论了错误消息的不一致。
如果您想要更一致的行为,请使用 str.format
。
通常,如果字符串中的占位符数量与传递的参数数量不匹配,Python 旧式字符串格式会报错:
>>> 'no.placeholders.here' % 'test'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: not all arguments converted during string formatting
但是,当传递的参数是用户定义的实例时 class,它会默默地忽略它:
>>> class Test(object): pass
>>> 'no.placeholders.here' % Test()
'no.placeholders.here'
这种行为似乎不一致,并导致了一些难以追踪的错误。为什么格式参数的类型对于此错误很重要?
这正是 %
格式 旧
%
格式 众所周知 因为它在参数处理方面的不一致导致异常与否取决于类型。只有两种方法可以使用 %
格式并避免不一致:
- 确保格式字符串包含正好一个格式字段并将对象传递给格式作为唯一正确的参数
- 使用
tuple
或dict
作为正确的参数。不要使用list
s、set
s 或Model
s。 仅tuple
和dicts
。
这些取自 documentation
If format requires a single argument, values may be a single non-tuple object. Otherwise, values must be a tuple with exactly the number of items specified by the format string, or a single mapping object (for example, a dictionary).
您的示例不属于这两种情况,因为您有 0 个格式字段,这与 1 不同,因此正确的参数 必须 是 tuple
或映射,但您传递的是字符串和用户定义的对象。因此,您处于 "undefined behaviour".
this 问题(在我的回答中)已经讨论了错误消息的不一致。
如果您想要更一致的行为,请使用 str.format
。