python - __str__ 和 __repr__ 有什么区别?

__str__有什么区别和 __repr__在 Python 中?

最佳答案

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

首先,让我重申Alex’s post中的要点。 :

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

  • 默认实现没用

    这主要是一个惊喜,因为 Python 的默认值往往相当有用。但是,在这种情况下,默认为 __repr__其作用如下:
    return "%s(%r)" % (self.__class__, self.__dict__)
    

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

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

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

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

    注意:我使用了 %r以上,不是 %s .你总是想用 repr() [或 %r格式化字符,相当于] 里面 __repr__实现,或者你正在击败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__如果您认为拥有一个在可读性方面出错的字符串版本会很有用。

    https://stackoverflow.com/questions/1436703/

    相关文章:

    python - 如何通过引用传递变量?

    python - **(双星/星号)和*(星号/星号)对参数有什么作用?

    python - "Least Astonishment"和可变默认参数

    python - 在一行中捕获多个异常( block 除外)

    python - 如何向字典添加新键?

    python - 如何克隆列表以使其在分配后不会意外更改?

    windows - 如何在 Windows 上安装 pip?

    python - 如何在 Python 中连接两个列表?

    python - 使用 __init__() 方法理解 Python super()

    android - 有没有办法在 Android 上运行 Python?