Python 中 str 和 repr 的区别 已翻译 100%

燕莳泗 投递于 2013/03/26 17:21 (共 7 段, 翻译完成于 04-11)
阅读 18486
收藏 11
4
加载中

Alex总结得很好,但是也太简洁了。

首先让我来重复下Alex的总结的要点:

  • 缺省实现是没用的(很难说不是,但是没错)
  • __repr__的目标是准确性
  • __str__的目标是可读性
  • 容器的__str__使用包含了对象的__repr__
晴风晓月
翻译于 2013/04/11 08:45
1

无用的缺省实现

这一点令人非常惊奇,因为Python的缺省设置通常都相对比较有用。然而,在这种情况下,__repr__的缺少实现表现为如下的代码:

return"%s(%r)"%(self.__class__,self.__dict__)
这样是非常危险的(如果对象之前相互引用很容易地就进入无限递归)。所以Python不会起作用。注意有一个缺省实现的情况:如果定义了__repr__,但没有定义__str__,对象将表现为__str__=__repr__。

用简单的术语来说,这意味着:几乎你实现的所有对象都应该有一个用于理解对象的__repr__函数。实现__str__是可选的:如果你需要一个看起来较好的打印功能(比如用于产生报表).

晴风晓月
翻译于 2013/04/11 08:57
1

__repr__的目标是准确性

直接了当地说,我不相信调试器。我并不确切知道如何使用任何调试器,也从来没有真正地使用过一个调试器。更进一步说,我相信调试器的大缺陷是它们的本质——我很久以前的调试发现绝大多数的失败都距真正的错误发生点很远。这使我对日志具有宗教般的热情。日志是一个正规的火灾和备份服务器系统的生命线。Python使得日志非常便于记录:利用某些项目特定的封装,你需要做的只是如下操作:

log(INFO,"I am in the weird function and a is",a,"and",b,"is",b,"but I got a null C — using default",default_c)
晴风晓月
翻译于 2013/04/11 09:15
1

但你还有最后一步需要做——确定你的每一个对象都实现了一个可用的repr函数,以使那样的代码可用。这也是"eval"出现的原因:如果你有足够的信息,所以eval(repr(c))==c就表明你知道所有的信息,因此知道c。如果那个太简单,但有点令人糊涂,请试着做一下。如果没有任何问题,那么请确定你有c的所有信息。我通常使用类eval的格式:"MyClass(this=%r, that=%r)" % (self.this, self.that)。这并不是说你能准确地构建MyClass,或那是正确的构造参数——但对于解释“这是你需要知道的关于这个实例的所有信息”是非常有用的。

注意,在上面我使用了%r而不是%s。你总是想在__repr__实现中用repr()[或者用与相同的%r格式字符串],或都你不管repr的准确性目标。你只是想能够区分MyClass(3)和MyClass("3")

晴风晓月
翻译于 2013/04/11 09:44
1

__str__的目标是可读性

特别说明它不特别在意准确性——注意str(3)==str("3")。类似的,你实现了一个IP地址的抽象,它很好地实现了类似192.168.1.1的str。当实现一个日期/时间抽象,str可能是“2010/4/12 15:35:22”,等等。它的目标是实现了一种使用户而不是程序员能够方便阅读的方式。去掉无用的数字,然后伪装成其它的类——只要它支持可读性,就是一种改进。

晴风晓月
翻译于 2013/04/11 09:51
1

容器的__str__使用包含了对象的__repr__

这看起来有点奇怪,不是吗?但下面的代码读起来应该是怎样的呢?

[mosheis,3,hello
world,thisisa list,oh I don't know, containing just 4 elements]

不太容易。需要明确的是,在容器中的字符串会发现一种方法,可以非常容易地影响到字符串的表示。请记住,Python面对歧义时拒绝去猜测。如果当你在输出一个list的时候,你想知道以上代码的结果,只需要以下代码:

print"["+", ".join(l)+"]"

(或许你能够指出对于dictionary的结果)。


晴风晓月
翻译于 2013/04/11 10:00
1

总结

在你实现的任何类里实现__repr__,这应该是第二性质。如果你认为实现一个__str__,在增加了歧义,但具有较少的错误,更好的可读性的情况下有效,那么就实现它。

晴风晓月
翻译于 2013/04/11 10:10
1
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接。
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
加载中

评论(6)

好铁
好铁
>>> class Sic(object): pass
...
>>> print str(Sic())
<__main__.Sic object at 0x8b7d0>
>>> print repr(Sic())
<__main__.Sic object at 0x8b7d0>
>>>
>>> class Sic(object):
... def __repr__(object): return 'foo'
...
>>> print str(Sic())
foo
>>> print repr(Sic())
foo
>>> class Sic(object):
... def __str__(object): return 'foo'
...
>>> print str(Sic())
foo
>>> print repr(Sic())
<__main__.Sic object at 0x2617f0>
>>>
blablambin
blablambin
居然是翻译的,我怎么看着很怪,也看不懂
51duchao
51duchao
翻译的真心晦涩,博主其实可以找点合适的例子适当延伸下的
黄雨
黄雨
看不懂!!!
简风
简风

引用来自“demonkit”的评论

stackoverflow上的,感谢翻译。说实话,英文的没大看懂。

其实中文翻译出来也还是很晦涩……
demonkit
demonkit
stackoverflow上的,感谢翻译。说实话,英文的没大看懂。
返回顶部
顶部