在python 2.7中错误格式化时误导"ValueError"

Bac*_*ach 1 python string-formatting

当我尝试以下错误代码时:

not_float = [1, 2, 3]
"{:.6f}".format(not_float)
Run Code Online (Sandbox Code Playgroud)

我得到以下误导ValueError:

ValueError: Unknown format code 'f' for object of type 'str'
Run Code Online (Sandbox Code Playgroud)

这是误导,因为它可能让我认为not_float是一个字符串.其他出现相同的消息non_float类型,如NoneType,tuple你有任何想法,为什么?并且:我应该期待这个错误消息,无论它是什么类型non_float,只要它不提供一些格式化方法f

另一方面,尝试:

non_date = 3
"{:%Y}".format(non_date)
Run Code Online (Sandbox Code Playgroud)

带来

ValueError: Invalid conversion specification
Run Code Online (Sandbox Code Playgroud)

信息量较少但误导性较小.

Mar*_*ers 5

str.format()方法,以及format()功能,调用.__format__()正在传递的对象的方法,沿一切合格后:结肠(.6f在这种情况下).

object.__format__()方法的默认实现是调用str(self)然后应用format()该结果.这是用C实现的,但在Python中看起来像:

def __format__(self, fmt):
    return format(str(self), fmt)
Run Code Online (Sandbox Code Playgroud)

正是这个调用抛出异常.对于一个list对象,例如:

>>> not_float.__format__('.6f')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: Unknown format code 'f' for object of type 'str'
Run Code Online (Sandbox Code Playgroud)

因为这在功能上与以下相同:

>>> format(str(not_float), '.6f')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ValueError: Unknown format code 'f' for object of type 'str'
Run Code Online (Sandbox Code Playgroud)

整数有一个自定义.__format__实现; 它不在str()内部使用,因为有特定于整数的格式化选项.它将值转换为字符串的方式不同.因此,它会抛出一个不同的异常,因为它无法识别%Y为有效的格式化字符串.

肯定会改进错误信息; 一个开放的Python bug讨论了这个问题.由于所有这些工作方式的变化,问题不再是Python 3.4中的问题; 如果格式字符串为空.__format__()将不再被调用.