【问题标题】:How do I permanently store data in a class python如何将数据永久存储在python类中
【发布时间】:2021-11-30 23:54:50
【问题描述】:

我必须在 Python 中创建一个推箱子游戏,并且我在我的推箱子类中定义了 find_player() 、 complete() 、 get_steps() 和 move() 方法。我需要创建一个 restart() 方法和一个 undo() 方法,但我不知道该怎么做。我找不到存储原始板或以前的板的方法。我尝试在__init__ 中定义另一个板,但它只是用self.__board 更新,而不是保存初始板。我还尝试在__init__ 中列出一个列表,并尝试将每个动作的“棋盘”附加到列表中,但它会更改列表中的每个棋盘。如果有人可以提供帮助,我已附上我的代码。

class Sokoban:
    """Your code here"""
    def __init__(self, board):
        self.__board = board
        self.__original_board = board
        self.__steps = 0
        self.__last_step = []
        self.__position = (0, 0)

    def restart(self):
        first_board = self.__original[0]
        new_board = []
        for i in range(len(first_board)):
             new_board.append(first_board[i])
        print(self.__original)
        return Sokoban(self.__original_board)

    def undo(self):
        return

  

def main(board):
    game = Sokoban(board)
    message = 'Press w/a/s/d to move, r to restart, or u to undo'
    print(message)
    while not game.complete():
        print(game)
        move = input('Move: ').lower()
        while move not in ('w', 'a', 's', 'd', 'r', 'u'):
            print('Invalid move.', message)
            move = input('Move: ').lower()
        if move == 'r':
            game.restart()
        elif move == 'u':
            game.undo()
        else:
            game.move(move)
    print(game)
    print(f'Game won in {game.get_steps()} steps!')


test_board = [
    ['*', '*', '*', '*', '*', '*', '*', '*'],
    ['*', ' ', ' ', ' ', ' ', ' ', ' ', '*'],
    ['*', 'P', ' ', '#', ' ', ' ', ' ', '*'],
    ['*', '*', '*', '*', '*', ' ', '#', '*'],
    ['*', 'o', ' ', ' ', ' ', ' ', ' ', '*'],
    ['*', ' ', ' ', ' ', ' ', ' ', 'o', '*'],
    ['*', '*', '*', '*', '*', '*', '*', '*']
]
main(test_board)

【问题讨论】:

  • 不要为变量使用__ 前缀。这不是 Pythonic。
  • @AKX,你能详细说明为什么__ 不是pythonic吗?你是说this 用例无效?
  • 名称修改适用于您要将一些名称混合到现有名称空间中,并且您不想意外使用与该名称空间中已有名称相同的名称。它主要用于代理类型(模仿其他类的 API)或混合类型。这些都是相当先进的技术,所以如果您还不了解它们,请不要担心。在任何情况下,你都没有在这里做这些事情。您的变量没有真正需要是私有的。您有像 get_steps 这样的方法,只需将 __steps 设为公共属性,就可以更自然地处理这些方法。
  • @Chris 是的——正如你链接的段落所说,私有字段的 Pythonic 约定是一个下划线。如果有的话,你很少需要隐藏的名称损坏字段。

标签: python class store


【解决方案1】:

如果您不想更改相同的值(一直到 test_board),则需要(深度)复制板列表列表。

import copy

# ...

   def __init__(self, board):
        self.__board = copy.deepcopy(board)
        self.__original_board = copy.deepcopy(board)

除此之外,也许.restart() 应该只是重置游戏对象的状态,而不是返回新对象?

    def __init__(self, board):
        self.__original_board = copy.deepcopy(board)
        self.restart()

    # ...

    def restart(self):
        self.__steps = 0
        self.__last_step = []
        self.__position = (0, 0)
        self.__board = copy.deepcopy(self.__original_board)

这样,一个简单的game.restart() 电话就可以了。

【讨论】:

  • 有没有什么方法可以在不导入任何东西的情况下做到这一点?我这样做是为了完成一项作业,我的讲师说我们不允许导入任何东西。
  • 当然,您可以自己实现二维复制(在这种情况下就足够了):self.__original_board = [row[:] for row in board]
  • 谢谢@AKX 我刚试过这个,它会重新启动,但它只会重新启动一次,然后如果用户在游戏中第二次按“r”,它就不会再次启动,有什么办法可以解决这个问题还是我无法解决的问题?
  • 当然可以修复。如果不查看您拥有的所有当前代码,很难判断出了什么问题。
  • 嗨,我把我的代码上传到了github.com/amistry24/130-Assignment/blob/master/assignment.py的github,所以你可以看到它。再次感谢您查看我的代码。 @AKX
【解决方案2】:

也许你可以使用内存数据库来存储你的测试数据。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-22
    • 2020-10-09
    相关资源
    最近更新 更多