python类的更新状态

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了python类的更新状态相关的知识,希望对你有一定的参考价值。

我正在尝试在python 3.6+中模拟一个3 x 3的板,其中0“ tile”可以上下,左右移动。我正在以列表形式实现状态。

class Tiles(object):

    def __init__(self, state, n):

        self.n = n
        self.state = state

        self.blank_index = self.state.index(0)

    def display(self):
        """ Tile state as a n*n board """
        for i in range(self.n):
            print(self.state[3 * i: 3 * (i + 1)])

    def move_up(self):
        blank = self.blank_index
        print("Blank is at position {}.".format(blank))
        if blank <= 2:
            return None
        else:
            up = self.state
            up[blank], up[blank - 3] = up[blank - 3], up[blank]
            Tiles.display(self)
            return Tiles(up, self.n)

    def move_down(self):
        blank = self.blank_index
        print("Blank is at position {}.".format(blank))
        if blank > 5:
            return None
        else:
            down = self.state
            down[blank], down[blank + 3] = down[blank + 3], down[blank]
            Tiles.display(self)
            return Tiles(down, self.n)

    def move_left(self):
        blank = self.blank_index
        print("Blank is at position {}.".format(blank))
        if blank == 0 or blank == 3 or blank == 6:
            return None
        else:
            left = self.state
            left[blank], left[blank - 1] = left[blank - 1], left[blank]
            Tiles.display(self)
            return Tiles(left, self.n)

    def move_right(self):
        blank = self.blank_index
        print("Blank is at position {}.".format(blank))
        if blank == 2 or blank == 5 or blank == 8:
            return None
        else:
            right = self.state
            right[blank], right[blank + 1] = right[blank + 1], right[blank]
            Tiles.display(self)
            return Tiles(right, self.n)

def move_seq(self):
    self.display()
    self.move_up()
    self.move_left()
    self.move_right()


def main():
    initial = [4,3,2,1,0,8,7,6,5]
    new_tiles = Tiles(initial, 9)
    move_seq(new_tiles)

if __name__ == '__main__':
    main()

但是我的输出是意外的...

[4, 3, 2]
[1, 0, 8]
[7, 6, 5]
[]
[]
[]
[]
[]
[]
Blank is at position 4.
[4, 0, 2]
[1, 3, 8]
[7, 6, 5]
[]
[]
[]
[]
[]
[]
Blank is at position 4.
[4, 0, 2]
[3, 1, 8]
[7, 6, 5]
[]
[]
[]
[]
[]
[]
Blank is at position 4.
[4, 0, 2]
[3, 8, 1]
[7, 6, 5]
[]
[]
[]
[]
[]
[]

[我很难理解为什么(1)函数self.move_up()中的move_seq(self)调用显示所需的输出,但随后的方法调用不显示,(2)为什么不保存更新的状态,即Blank is at position 4和( 3)为什么在display中还有多余的空列表对象打印。

谢谢您帮助我理解!

答案

[当您调用Tiles.display(self)时,您没有在调用相同的Tiles对象。相反,这是实例化一个新的“ Tiles”对象,并在一个新的类实例上调用display方法。因此,后续的self.state属性不会被修改。

您应该调用self.display,它将重用单个Titles类实例的相同state属性。

此外,您永远不会更新初始对象的blank_index属性。例如,在此代码中:

    def move_up(self):
        blank = self.blank_index
        print("Blank is at position {}.".format(blank))
        if blank <= 2:
            return None
        else:
            up = self.state
            up[blank], up[blank - 3] = up[blank - 3], up[blank]
            self.display()
            return Tiles(up, self.n)

空白将始终是开头的“ 4”。相反,您应该在修改state属性之后更新此属性:

    def move_up(self):
        blank = self.blank_index
        print("Blank is at position {}.".format(blank))
        if blank <= 2:
            return None
        else:
            up = self.state
            up[blank], up[blank - 3] = up[blank - 3], up[blank]
            self.blank_index = self.state.index(0)
            self.display()

然后您将创建一个新的Tiles实例并返回它……但是,您从未使用过这个新对象,因为您的所有调用都在此

# Note: You should not use the variable "self" outside of a class... in this instance it would make more sense to use something like "obj" for object.
def move_seq(obj):
    obj.display()
    obj.move_up()
    obj.move_left()
    obj.move_right()

是INITIAL对象的调用方法!

如果Tiles的显示方法是作为静态函数编写的,则在其中将状态作为参数传递给您,然后您就可以毫无问题地调用Tiles.display,因为该方法将不再需要访问“ self”的任何属性。 “以产生预期的结果。

以上是关于python类的更新状态的主要内容,如果未能解决你的问题,请参考以下文章

有条件地导入 python 类的片段

从prop更新更新状态将导致循环错误

VSCode自定义代码片段13——Vue的状态大管家

VSCode自定义代码片段13——Vue的状态大管家

VSCode自定义代码片段13——Vue的状态大管家

从第二个片段访问时 ViewModel 数据丢失状态