__str__在方法中打印行

时间:2015-06-07 19:33:48

标签: python

我正在努力改进你在python的codecademy课程中制作的“战舰”游戏,我决定我的第一步是实现类。

我预期的代码输出是五行O O O O O。当我在for循环中只使用一个print语句时会实现这一点,但它会引发错误说明:

Traceback (most recent call last):
File "D:/PythonProjects/Battleship/Main.py", line 21, in <module>
    print(board)
TypeError: __str__ returned non-string (type NoneType)

当我离开代码时,它不会抛出错误但只会打印一行O的

有问题的代码:

class Board(object):
    """Creates the game board"""
    board = []

    def __init__(self, size):
        self.size = size
        for x in range(size):
            self.board.append(["O"] * size)

    def __str__(self):
        for row in self.board:
            display = (" ".join(row))

        return display

board = Board(5)
print(board)

2 个答案:

答案 0 :(得分:2)

您的__str__方法会在循环的每次迭代中为display分配一个新值。相反,你可以做类似的事情:

def __str__(self):
    accumulator = ""
    for row in self.board:
        accumulator += " ".join(row) + "\n"
    return accumulator

或者更简洁

def __str__(self):
    return "\n".join([" ".join(row) for row in self.board])

除了那些一遍又一遍地设计这个的人之外,帮助每一个进入OOP的新入学的CS学生,如果它继承自list,这个课就变得容易多了。它是描述游戏板的列表的容器 - 将其作为列表本身....

class Board(list):
    def __init__(self, size):
        """Square board of length `size`"""
        for row in range(size):
            self.append(["O"] * size)

    def __str__(self):
        return "\n".join([" ".join(row) for row in self])

答案 1 :(得分:2)

首先,您不应该为board使用类属性。这样做将在所有Board实例之间共享实例,因此您将继续添加到同一列表中。而是为您创建的每个对象创建一个新列表:

class Board(object):
    def __init__(self, size):
        self.size = size
        self.board = []
        for x in range(size):
            self.board.append(["O"] * size)

现在,为了回答你的问题,你实际上不应该得到那个类型的错误,因为当你在display的循环中继续覆盖__str__时,它确实得到至少一个不是{的值。 {1}},假设None不为空(在您的示例中不是)。

但是你要做的是收集所有行并用新行符号连接它们:

board

或者在一行中:

def __str__(self):
    display = []
    for row in self.board:
        display.append(" ".join(row))
    return '\n'.join(display)