__str__ 和 __repr__ 有什么区别?

新手上路,请多包涵

__str____repr__ 在 Python 中有什么区别?

原文由 Casebash 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 288
2 个回答

亚历克斯 总结得很好,但令人惊讶的是,他过于简洁了。

首先,让我重申一下 Alex 帖子中的 要点:

  • 默认实现是无用的(很难想到哪个不是,但是是的)
  • __repr__ 目标是明确的
  • __str__ 目标是可读
  • 容器的 __str__ 使用包含的对象 __repr__

默认实现是无用的

这主要是一个惊喜,因为 Python 的默认值往往相当有用。但是,在这种情况下,默认为 __repr__ 其作用如下:

 return "%s(%r)" % (self.__class__, self.__dict__)

会太危险(例如,如果对象相互引用,太容易进入无限递归)。所以 Python 解决了。请注意,有一个默认值是正确的:如果定义了 __repr__ ,并且未定义 __str__ ,则该对象的行为就像 __str__=__repr__

这意味着,简单来说:几乎每个您实现的对象都应该有一个功能性的 __repr__ 可用于理解该对象。实施 __str__ 是可选的:如果您需要“漂亮的打印”功能(例如,由报告生成器使用),请执行此操作。

__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)

但是你必须做最后一步——确保你实现的每个对象都有一个有用的 repr,这样这样的代码才能正常工作。这就是为什么出现“评估”的原因:如果您有足够的信息 eval(repr(c))==c ,这意味着您知道关于 c 的所有信息。如果这足够简单,至少以一种模糊的方式,那就去做吧。如果没有,请确保您有足够的关于 c 的信息。我通常使用类似 eval 的格式: "MyClass(this=%r,that=%r)" % (self.this,self.that) 。这并不意味着您实际上可以构造 MyClass,或者那些是正确的构造函数参数——但它是一种有用的形式来表达“这是您需要了解的有关此实例的所有信息”。

注意:我在上面使用 %r ,而不是 %s 。您总是想在 --- 中使用 repr() [或 %r 格式化字符,等同于] __repr__ 实现目标,否则您将失败。您希望能够区分 MyClass(3)MyClass("3")

__str__ 的目标是可读的

具体来说,它并不是要明确 - 注意 str(3)==str("3") 。同样,如果您实现 IP 抽象,让它的 str 看起来像 192.168.1.1 就可以了。实现日期/时间抽象时,str 可以是“2010/4/12 15:35:22”等。目标是以用户而非程序员想要阅读的方式表示它。砍掉无用的数字,伪装成其他类——只要它支持可读性,就是一种改进。

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

这似乎令人惊讶,不是吗?它有点小,但如果它使用他们的 __str__ ,它的可读性如何?

 [moshe is, 3, hello
world, this is a list, oh I don't know, containing just 4 elements]

不是特别的。具体来说,容器中的字符串会发现很容易干扰其字符串表示。面对歧义,请记住,Python 抵制猜测的诱惑。如果您在打印列表时想要上述行为,只需

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

(您可能还可以弄清楚如何处理字典。

概括

为您实现的任何类实现 __repr__ 。这应该是第二天性。实施 __str__ 如果您认为拥有一个在可读性方面出错的字符串版本会很有用。

原文由 moshez 发布,翻译遵循 CC BY-SA 4.0 许可协议

我的经验法则: __repr__ 是给开发者的, __str__ 是给客户的。

原文由 Ned Batchelder 发布,翻译遵循 CC BY-SA 2.5 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题