当前位置 : 主页 > 编程语言 > python >

__Str__和__repr__有什么区别?

来源:互联网 收集:自由互联 发布时间:2022-06-18
文章来源:​​__Str__和__repr__有什么区别? - 代码领悟code05.com​​ 提问:__Str__和__repr__有什么区别? Python中的​​__str__​​​和​​__repr__​​有什么区别? 回答: ​​Alex​​总结

文章来源:​​__Str__和__repr__有什么区别? - 代码领悟code05.com​​

提问:__Str__和__repr__有什么区别?

Python中的​​__str__​​​和​​__repr__​​有什么区别?

回答:

​​Alex​​总结得很好,但令人惊讶的是,过于简洁。

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

  • 默认实现是无用的(很难想到一个不会是,但是是的)
  • ​​__repr__​​目标是毫不含糊
  • ​​__str__​​目标是可读
  • Container'S​​__str__​​​使用contained objects'​​__repr__​​

​默认实现是无用的​

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

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

会太危险(例如,如果对象相互引用,那么太容易进入无限递归)。 所以蟒蛇逃跑了。 请注意,有一个默认值为true:如果定义了​​__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"的事情出现了:如果你有足够的信息,所以​​eval(repr(c))==c​​​,这意味着你知道所有关于​​c​​​的事情。 如果这很容易,至少在一个模糊的方式,做到这一点。 如果没有,无论如何都要确保你有足够的关于​​c​​​的信息。 我通常使用类似eval的格式:​​"MyClass(this=%r,that=%r)" % (self.this,self.that)​​。 这并不意味着你实际上可以构造MyClass,或者那些是正确的构造函数参数—但它是一个有用的形式来表达"这是你需要知道的关于这个实例的一切"。

注意:我在上面使用了​​__repr__​​​,而不是​​%s​​​。 你总是想在​​__repr__​​​实现中使用​​__repr__​​​[或​​__repr__​​​格式化字符,等价地],或者你正在击败repr的目标。 您希望能够区分​​MyClass(3)​​​和​​MyClass("3")​​。

​​__str__​​​的目标是可读​

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

​Container'S​​__str__​​​使用contained objects'​​__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__​​如果你认为有一个字符串版本在可读性方面出错会很有用。

网友评论