带有 None 的 f 字符串格式说明符抛出 TypeError

f-string format specifier with None throws TypeError

将纯 f 字符串与 NoneType 对象一起使用有效:

>>> a = None
>>> f'{a}'
'None'

但是,当使用格式说明符时,它会中断--- str.format():

>>> f'{a:>6}'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported format string passed to NoneType.__format__

>>> '{:>6}'.format(a)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported format string passed to NoneType.__format__

出乎意料的是,(至少对我而言)旧的 C 风格字符串格式有效:

>>> '%10s' % a
'      None'

这是怎么回事?我不明白为什么 f'{a:>6}' 不计算为 ' None'。为什么格式说明符应该打破它?

这是 python 中的错误吗?如果是bug,我该如何修复?

None 不是字符串,所以 f'{None:>6}' 没有意义。您可以使用 f'{None!s:>6}' 将其转换为字符串。 !a!s!r 分别调用对象上的 ascii()str()repr()

None 不支持格式说明符。由每个对象类型决定它如何处理格式说明符,the default is to reject them:

The __format__ method of object itself raises a TypeError if passed any non-empty string.

None 继承此默认值。

您似乎期望 None 以与字符串相同的方式处理格式说明符,其中 '{:>6}'.format('None') == ' None'。这听起来像是您希望所有类型都像字符串一样处理格式说明符,或者您希望字符串行为是默认的。字符串处理格式说明符的方式是特定于字符串的;其他类型有自己的处理方式。


您可能会想,嘿,为什么 %10s 没有失败呢?首先,s 请求在任何进一步处理之前通过 str 将参数转换为字符串。其次,printf 样式字符串格式中的所有转换说明符处理都由 str.__mod__ 执行;它从不委托参数来弄清楚转换说明符的含义。

上面接受的答案解释了原因。我有效使用的解决方案是:

f"{mystring:.2f}" if mystring is not None else ""