Python中__str____repr__的区别是什么?

推荐答案

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

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

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

Default implementation is useless

这在很大程度上是令人惊讶的,因为Python的缺省值往往相当有用.但是,在本例中,如果默认值为__repr__,则如下所示:

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

太危险了(例如,如果对象相互引用,就很容易陷入无限递归).所以巨蟒逃走了.请注意,有一个默认值为true:如果定义了__repr__,而没有定义__str__,则对象的行为将与__str__=__repr__类似.

这意味着,简单地说:几乎你实现的每个对象都应该有一个功能__repr__,可以用来理解对象.实现__str__是可选的:如果需要"漂亮的打印"功能(例如,由报表生成器使用),可以这样做.

The goal of 100 is to be unambiguous

让我直截了当地说吧-我不相信调试器.我真的不知道如何使用任何调试器,而且从来没有认真使用过.此外,我认为调试器的最大缺点是它们的基本性质--我调试的大多数故障都发生在很久很久以前,在遥远的银河系.这意味着我确实怀着宗教的热情相信伐木.日志(log)记录是任何像样的"即火即忘"服务器系统的命脉.Python使日志(log)记录变得很容易:可能有一些特定于项目的包装器,您所需要的只是一个

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的信息.我通常使用类似计算的格式:"MyClass(this=%r,that=%r)" % (self.this,self.that).这并不意味着您可以实际构造MyClass,或者这些都是正确的构造函数参数-但它是一种有用的形式来表达"这就是您需要了解的关于此实例的一切".

注意:我用的是上面的%r,不是%s.您总是希望在__repr__实现中使用repr()[或%r个格式化字符,相当于],否则您就会与repr的目标背道而驰.您希望能够区分MyClass(3)MyClass("3").

The goal of 100 is to be readable

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

Container’s 100 uses contained objects’ 101

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

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

不是很好.具体地说,容器中的字符串会发现太容易干扰其字符串表示.请记住,面对模棱两可的情况,Python抵制住了猜测的诱惑.如果在打印列表时需要上述行为,只需

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

(你可能还可以想出如何处理字典.

Summary

对于你实现的任何类,实现__repr__.这应该是第二天性.如果您认为字符串版本有助于提高可读性,请实现__str__.

Python相关问答推荐

检测包是否作为 __init__.py 中的程序运行

创建一个由 1-90 的唯一数字组成的 M*N 矩阵

如何计算Pandas 数据框中单元格内的行数,这些行数不是空行

如何使用 Lambda 赋予 HTTP API 或 REST API 不更新的能力?

通过python在字典内的字典中打印数字

使用 Ipywidgets 按索引的 DataFrame 交互式绘图

Python:根据名称中的时间戳查找和打印重复文件

如何在 map 中插入点

我通过postman 获得状态代码 200,但通过 request.get 我获得状态代码 500

pip 和命令行的问题

如何为 ManyToMany 字段添加排序?

带有Pandas 的ValueError应用函数返回可变形状的输出

如何使用 sys.argv 将字符串变量从 shell 脚本传递给 python?

Pandas df 按计数元素分组

在 __next__() 中修改之前返回对象

如何创建字典来查找丢弃的零?

计算频率数据帧的众数、中位数和偏度

如何将一个模块导入另一个模块

是否可以使用 pyscript 在浏览器上运行使用 pygame 制作的游戏?

如何在Pandas 中按天分组?