为什么使用%r与元组一起时会出现“Not all arguments converted”的错误?

3
请问为什么我在使用 %r 与元组时会出现以下错误?
>>> repr((1,2))
'(1, 2)'
>>> class Foo(object):
...     def __init__(self,vals):
...             self.vals=vals
...     def __repr__(self):
...             return "Foo(%r)" % self.vals
... 
>>> foo = Foo((1,2))
>>> foo
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 5, in __repr__
TypeError: not all arguments converted during string formatting

如何适当地打印 __repr__?我应该使用 %srepr(self.vals) 吗?


你可以轻松地自己检查使用“%s”时会发生什么,为什么你觉得需要来这里问呢? - Inbar Rose
2
@InbarRose:因为对于不熟悉“%”字符串格式化运算符的人来说,这种行为是出乎意料的。 - Martijn Pieters
@Inbar "请问有人能解释一下为什么我在使用%r与元组时会出现以下错误吗?" 这就是我提出这个问题的原因。我对为什么会出现错误以及处理它的最合适(符合Python风格)的方式很感兴趣。 - Tim
1个回答

7
"% 运算符接受一个元组作为参数,因此你基本上在执行以下操作:"
'Foo(%r)' % (1, 2)

self.vals包装在一个只有一个元素的元组中:

'Foo(%r)' % (self.vals,)

原则上,您也可以使用变量中定义的字符串:

REPRFORMAT % (self.vals,)

如果您想让变量(可能来自配置文件)决定如何格式化self.vals,可以使用此方法。

您也可以使用.format()方法

return 'Foo({0!r})'.format(self.vals)

这种格式使得输入更加灵活,例如你可以单独处理 vals 元组中的每个项:

return 'Foo(({0[0]:04d}, {0[1]:02d}))'.format(self.vals)

在您的示例输入中,这将导致Foo((0001, 04))

有关使用的“推荐”方法是否有共识?就个人而言,我认为“Foo(%s)”%repr(self.vals)最容易阅读,但正如我上面提到的那样,这引出了一个问题,即为什么您会使用%r。 - Tim
1
@Tim:.format() 字符串格式化方法已经被添加以替换 %,尽管后者的语法在 Python 3 中仍然存在。 - Martijn Pieters
@Tim:进一步扩展,提供一些使用“%r”的论点。 - Martijn Pieters
谢谢提供信息。我到目前为止还没有接触过.format()。考虑到我的简单应用场景,我认为我会暂时坚持使用%s,因为我认为它更易读。 - Tim

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接