问题描述
我试图了解 Python 中 f 字符串的以下行为:
f"{str((1,2,3)):>10}"
但是,如果我删除显式转换,该行会引发 TypeError: unsupported format string passed to tuple.__format__
:
f"{(1,3):>20}"
没有给定任何格式时没有问题:
f"{(1,3)}"
我原以为 f-string 会自动将元组转换为字符串,然后强制执行格式要求。情况似乎并非如此。有人可以解释一下吗?除了通过 str()
进行显式转换之外,还有其他解决方法吗?
解决方法
您可以通过使用文字 !s
在字符串的格式部分明确指定转换为字符串来实现,如下所示:
f"{(1,2,3)!s:>10}'
这是必需的,因为宽度规范 :>10
仅适用于字符串。
正如您所经历的,有一些魔法正在发生。但是,并非在格式化之前将每个项目都转换为字符串。
TypeError 解释了 Python 试图做什么:它试图调用元组的 __format__
方法。但它失败了,因为 tuple.__format__
不需要 >
参数。如果您要微调自己班级的格式,您可以这样做:
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
因此,根据 MyType.__format__
生成和返回字符串取决于您自己的 format_spec
。
具有处理 __format__
之类的 format_spec
方法的 >10
方法的一种原生 Python 类型是字符串类。这就是 f"{str((1,3)):>10}"
起作用的原因。
您可以做的是使用 !
标记将元组转换为字符串 - 这相当于使用 str()
但不那么冗长:
f"{(1,3)!s:>10}"
输出:
' (1,3)'
根据需要在左侧添加一个空格。