为什么将格式化信息添加到具有元组值的 f 字符串会引发 TypeError?
Why does adding formatting information to a f-string with tuple values raise a TypeError?
我试图了解 Python 中 f 弦的以下行为:
通过 str()
显式转换元组值的下一行工作正常。
f"{str((1,2,3)):>10}"
但是,如果我放弃显式转换,该行会引发 TypeError: unsupported format string passed to tuple.__format__
:
f"{(1,2,3):>20}"
没有给出任何格式时没有问题:
f"{(1,2,3)}"
我原以为 f-string 会自动将元组转换为字符串,然后强制执行格式要求。情况似乎并非如此。有人可以解释吗?除了通过 str()
进行显式转换之外,还有其他解决方法吗?
您可以通过在字符串的格式部分用文字 !s
明确指定到字符串的转换来实现,如下所示:
f"{(1,2,3)!s:>10}'
这是必需的,因为宽度规范 :>10
仅适用于字符串。
如您所见,有些神奇的事情正在发生。但是,不是每个项目在格式化之前只是被转换为字符串。
TypeError 解释了 Python 试图做什么:它试图调用元组的 __format__
方法。但它失败了,因为 tuple.__format__
不期望 >
参数。如果你要微调你自己的 class 的格式,你可以这样做:
class MyType:
def __init__(self, value):
self.value = value
def __format__(self, format_spec):
return f"this is the value {self.value} formatted against {format_spec}"
if __name__ == '__main__':
d = MyType(6)
print(f"{d:>10}")
输出:
this is the value 6 formatted against >10
所以根据format_spec
.
生成和return一个字符串将取决于你自己MyType.__format__
一个原生 Python 类型有一个 __format__
方法来处理 format_spec
像 >10
这样的字符串 class。这就是 f"{str((1,2,3)):>10}"
起作用的原因。
你可以做的是使用 !
标记将元组转换为字符串——这等同于使用 str()
但不那么冗长:
f"{(1,2,3)!s:>10}"
输出:
' (1, 2, 3)'
根据需要在左侧添加一个 space。
我试图了解 Python 中 f 弦的以下行为:
通过 str()
显式转换元组值的下一行工作正常。
f"{str((1,2,3)):>10}"
但是,如果我放弃显式转换,该行会引发 TypeError: unsupported format string passed to tuple.__format__
:
f"{(1,2,3):>20}"
没有给出任何格式时没有问题:
f"{(1,2,3)}"
我原以为 f-string 会自动将元组转换为字符串,然后强制执行格式要求。情况似乎并非如此。有人可以解释吗?除了通过 str()
进行显式转换之外,还有其他解决方法吗?
您可以通过在字符串的格式部分用文字 !s
明确指定到字符串的转换来实现,如下所示:
f"{(1,2,3)!s:>10}'
这是必需的,因为宽度规范 :>10
仅适用于字符串。
如您所见,有些神奇的事情正在发生。但是,不是每个项目在格式化之前只是被转换为字符串。
TypeError 解释了 Python 试图做什么:它试图调用元组的 __format__
方法。但它失败了,因为 tuple.__format__
不期望 >
参数。如果你要微调你自己的 class 的格式,你可以这样做:
class MyType:
def __init__(self, value):
self.value = value
def __format__(self, format_spec):
return f"this is the value {self.value} formatted against {format_spec}"
if __name__ == '__main__':
d = MyType(6)
print(f"{d:>10}")
输出:
this is the value 6 formatted against >10
所以根据format_spec
.
MyType.__format__
一个原生 Python 类型有一个 __format__
方法来处理 format_spec
像 >10
这样的字符串 class。这就是 f"{str((1,2,3)):>10}"
起作用的原因。
你可以做的是使用 !
标记将元组转换为字符串——这等同于使用 str()
但不那么冗长:
f"{(1,2,3)!s:>10}"
输出:
' (1, 2, 3)'
根据需要在左侧添加一个 space。