python - 对 list.copy() 所做的修改适用于列表
问题描述
我正在尝试使用面向对象的编程在 python 3 中为国际象棋游戏建模。我正在使用的一个类是 Board,它包含一个矩阵(8x8 列表列表)和另一个对象。我还创建了一个简单的__str__
方法来可视化棋盘。
这是 Board 类定义的一部分:
class Board:
def __init__(self, pieces: list):
self.container = [[pieces[i] for i in range(8)], # Whites
[pieces[i] for i in range(8, 16)], # White pawns
[None] * 8,
[None] * 8,
[None] * 8,
[None] * 8,
[pieces[i] for i in range(16, 24)], # Black pawns
[pieces[i] for i in range(24, 32)]] # Blacks
def __str__(self):
str_copy = self.container.copy()
for i in range(8):
for j in range(8):
if isinstance(str_copy[i][j], King):
str_copy[i][j] = 'K'
elif isinstance(str_copy[i][j], Queen):
str_copy[i][j] = 'Q'
elif isinstance(str_copy[i][j], Rook):
str_copy[i][j] = 'R'
elif isinstance(str_copy[i][j], Knight):
str_copy[i][j] = 'N'
elif isinstance(str_copy[i][j], Bishop):
str_copy[i][j] = 'B'
elif isinstance(str_copy[i][j], Pawn):
str_copy[i][j] = 'P'
elif str_copy[i][j] is None:
str_copy[i][j] = '_'
return ''.join([str(line) + '\n' for line in str_copy])
我的问题是,在我的代码中的某个时间点Board.container
似乎被str_copy
. 我真的想不通为什么。如果您想查看它,这是完整的代码:pastebin
非常感谢你的帮助 !
解决方案
这太复杂了。首先,每个部分都应该有自己的__str__
方法,例如,
class Bishop:
...
def __str__(self):
return 'B'
然后
class Board:
def __init__(self, pieces: list):
self.container = [pieces[:8], # white back row
pieces[8:16], # white pawns
[None] * 8,
[None] * 8,
[None] * 8,
[None] * 8,
pieces[16:24], # black pawns
pieces[24:32] # black back row
]
@staticmethod
def _square_to_str(x):
return '_' if x is None else str(x)
def __str__(self):
return '\n'.join(''.join(map(Board._square_to_str, row))
for row in self.container)
推荐阅读
- python - 什么 channel_argument 会以与 grpc 客户端调用中的 timeout 参数等效的方式设置超时?
- python - 如何在 Python 中的泛型类型上使用 isinstance
- python - 无法在 Jupyter 笔记本中使用 arcgis 包
- r - unserialize(node$con) 中的错误:无法检索 MultisessionFuture (future_lapply-1) 的值
- snowflake-cloud-data-platform - 雪花 sql udtf 连接性能
- google-apps-script - 将数字列表(包括范围)从单个单元格拆分到列
- python - 如何根据他们的行堆叠数据?Python
- com - 如何在 IronPython 中访问 COM 函数的返回值?
- c# - 导航问题,必须点击两次后退图标
- docker - 从 docker 进行“拨号 tcp i/o 超时”的错误处理