2

刚刚遇到一个示例 Fraction 类,不太确定这两种方法之间的区别是什么。一旦__str__实施就不会show变得多余?

def __str__(self):
    return str(self.num)+"/"+str(self.den)

def show(self):
    print(self.num,"/",self.den)

我意识到__str__这是一种神奇的方法,它的实现负责处理需要类的字符串版本的任何上下文。只是看不到show(self)方法的重点吗?


编辑

是显示大多数类需要的通用方法吗?
我的问题是,如果我有一个分数 x,那么我需要做的就是print(x),我将看到1\2或实例包含什么 - 那么为什么还要费心实现一个额外的方法show呢?

4

3 回答 3

8

拥有__str__方法的目的是创建对象的字符串表示。__str__ 应该返回一个字符串。如果 的实现__str__改为打印字符串表示并且不返回任何内容,则当在字符串上下文中使用对象时TypeError将引发 a 。举个例子:

def __str__(self):
        print '%f/%f'%(self.num,self.den)

如果我们像这样显示一个分数对象:

f = Fraction(1,2)
print f

我们得到一个例外:

Traceback (most recent call last):
  File "/Users/.../Desktop/...", line 13, in <module>
    print f
TypeError: __str__ returned non-string (type NoneType)
>>> 

这是因为__str__用于获取对象的字符串表示形式,而不是打印它(按照惯例,只要返回字符串,您就可以打印)。这就是print语句/函数与方法一起使用的目的__str__

另一方面,像这样的方法show

def show(self):
        print(self.num,"/",self.den) #or even print(self) (for the last part of answer)

本质上等同print(f)于上述情况(除了它在操作数旁边包含空格)。show用于输出字符串表示,同时__str__获取表示

但是,在构造字符串表示时,可能会添加show不合适/不必要的额外逻辑,因此同时使用这两种方法是有意义的。

但是,您可以使用类似showwhereprint语句不合适的方法,即:

if f.show(): pass
if print(f): pass #raise exception
于 2013-10-19T08:42:25.747 回答
4

__str__方法非常小心地确保所有内容都是 a str,因此它返回 a str

show方法依赖于 print 隐式转换self.numself.denstr 。它将结果显示为副作用,并返回 None

print将在每个参数之间插入一个空格。

>>> str(3)+"/"+str(5)
'3/5'
>>> print(3,"/",5)
3 / 5

如果你不关心额外的空间,真的没有理由不使用

def show(self):
    print(self)

也许作者认为不那样做会更清楚。

当您尝试创建子类时,解耦show和这种方式也可能令人惊讶。__str__如果子类覆盖了__str__,您可能希望更改也会反映在其中show

于 2013-10-19T08:40:06.490 回答
3

__str__是一个魔术方法,每次将对象视为字符串时都会调用它,例如str(fraction_instance)

于 2013-10-19T08:28:15.210 回答