为何for循环在__str__语句中迭代到NoneType?

2 投票
3 回答
2045 浏览
提问于 2025-04-17 03:04

我在用Python写代码,想创建一个叫做ShapeSet的实例,这个实例里要包含一系列Shape的实例,并且我希望它能把这些Shape实例的列表打印出来。

在代码的其他地方,我可以使用for循环而没有遇到任何错误。但是,当我尝试使用print语句时,它会把整个列表都打印出来,最后却报错:__str__ returned non-string (type NoneType)

我不明白为什么它在这里不能理解要在列表的末尾停止。(至少我觉得是这样)。

任何帮助都非常感谢。

class ShapeSet:
    def __init__(self):
        """
        Initialize any needed variables
        """
        self.collect = []
        self.place = None

    def __iter__(self):
        """
        Return an iterator that allows you to iterate over the set of
        shapes, one shape at a time
        """
        self.place = 0
        return self

    def next(self):
        if self.place >= len(self.collect):
            raise StopIteration
        self.place = self.place + 1
        return self.collect[self.place-1]

    def addShape(self, sh):
        """
        Add shape sh to the set; no two shapes in the set may be
        identical
        sh: shape to be added
        """
        s_count = 0
        c_count = 0
        t_count = 0
        self.collect.append(sh)
        for i in self.collect:
            if type(sh) == Square and type(i) == Square:
                if sh.side == i.side:
                    s_count = s_count + 1
                if s_count == 2:
                    self.collect.remove(sh)
                    print('already there')
            if type(sh) == Circle and type(i) == Circle:
                if sh.radius == i.radius:
                    c_count = c_count + 1
                if c_count == 2:
                    self.collect.remove(sh)
                    print('already there')
            if type(sh) == Triangle and type(i) == Triangle:
                if sh.base == i.base and sh.height == i.height:
                    t_count = t_count + 1
                if t_count == 2:
                    self.collect.remove(sh)
                    print('already there')

    def __str__(self):
        """
        Return the string representation for a set, which consists of
        the string representation of each shape, categorized by type
        (circles, then squares, then triangles)
        """
        for i in self.collect:
            if type(i) == Square:
                print ('Square with measurements ' +  str(i.side))
            if type(i) == Circle:
                print ('Circle with measurements ' + str(i.radius))
            if type(i) == Triangle:
                print ('Triangle with measurements, base/height ' + str(i.base)+ ' ' + str(i.height))

3 个回答

0

你可以在str方法里面做任何你想做的事情,比如循环、打印输出、添加更多逻辑等等,只要最后返回一个字符串,比如返回"",这样就能满足要求了。

在你的情况下:

def __str__(self):
    """
    Return the string representation for a set, which consists of
    the string representation of each shape, categorized by type
    (circles, then squares, then triangles)
    """
    for i in self.collect:
        if type(i) == Square:
            print ('Square with measurements ' +  str(i.side))
        if type(i) == Circle:
            print ('Circle with measurements ' + str(i.radius))
        if type(i) == Triangle:
            print ('Triangle with measurements, base/height ' + str(i.base)+ ' ' + str(i.height))
    return ""
3

你写了

def __str__(self):
    """
    **Return** the string representation for a set, which consists of
    the string representation of each shape, categorized by type
    (circles, then squares, then triangles)
    """

但是你没有 return 任何东西 - 你只是打印了一些内容。

在你所有的类上加一个合适的 __str__ 方法:

class Square:

    def __str__(self):
        return 'Square with measurements ' +  str(i.side)

class Circle:

    def __str__(self):
        return 'Circle with measurements ' + str(i.radius)

# and so on

还有一个关于你的 ShapeSet 的表示方法:

class ShapeSet:

    def __str__(self):
        return '\n'.join(str(x) for x in self.collect)

现在你可以用 print(some_shapeset) 来打印它,就像用 print(some_circle) 打印圆形一样。

3

看看你在 __str__ 函数里的文档说明。你应该是要“返回字符串表示”,而不是直接用 print 打印出来。因为在 __str__ 函数里没有 return 语句,所以它返回的是 None,而 print 对这个就处理不了。

所以,你应该真正地 return 你想要的字符串,然后让外部的 print 来显示它:

def __str__(self):
    """
    Return the string representation for a set, which consists of
    the string representation of each shape, categorized by type
    (circles, then squares, then triangles)
    """
    strings = []
    for i in self.collect:
        if type(i) == Square:
             strings.append('Square with measurements ' +  str(i.side))
        if type(i) == Circle:
            strings.append('Circle with measurements ' + str(i.radius))
        if type(i) == Triangle:
            strings.append('Triangle with measurements, base/height ' + str(i.base)+ ' ' + str(i.height))
    return '\n'.join(strings)

撰写回答