python - 使用不同的构造函数创建类的副本
问题描述
所以我有一个班级女王。我想将此实例传递给一个函数,并在该函数中创建(基于传入的类可能是 Rook、King 等)Queen(或 Rook 或 King)的新实例,但具有不同的初始输入参数. 我希望这很简单
我可以从实用程序类中做到这一点,但我想要 Board 类中的功能。
# This part works if I do it in the utility class
board.removePiece(pos6)
board.removePiece(pos2)
board.placePiece(pos6, Queen("Black", pos6))
# This part doesnt work
def capturePiece(self, pieceA, pieceB):
temp = pieceA
pos = pieceB.position
self.removePiece(pieceB.position)
self.removePiece(pieceA.position)
self.placePiece(pos, temp.create_another(temp.team, pos))
# From the Queen, King, etc, class
def create_another(self, team, position): # Returning constructor
return type(self, team, position)()
解决方案
这可能是基类上的类方法的一个很好的例子:
class Piece:
@classmethod
def create_another(cls, team, position):
return cls(team, position)
def __init__(self, team, position):
self.team = team
self.position = position
def __str__(self):
return str("{} team {} at {}".format(self.__class__,
self.team, self.position))
class Queen(Piece):
pass
class Rook(Piece):
pass
class Board:
def placePiece(self, pos, piece):
print("Place {} at {}".format(piece, pos))
def removePiece(self, position):
print("Remove piece at " + str(position))
def capturePiece(self, pieceA, pieceB):
temp = pieceA
pos = pieceB.position
self.removePiece(pieceB.position)
self.removePiece(pieceA.position)
self.placePiece(pos, temp.create_another(temp.team, pos))
def test(self):
r = Rook("White", "d4")
q = Queen("Black", "d6")
self.capturePiece(q, r)
你可以试试:
b = Board()
b.test()
按预期显示:
Remove piece at d4
Remove piece at d6
Place <class '__main__.Queen'> team Black at d4 at d4
但这通常是一个糟糕的设计。反复销毁和创建新对象比简单地更改它们的属性要昂贵得多。无论如何,在真正的棋盘上,您不会创建新棋子,而是移动它们,因此您没有真正的理由不实现移动方法来更改 Piece 基类上的位置。
推荐阅读
- javascript - 如何在 Flutter 移动应用中使用 JS 库和 JS 函数?
- flutter - 导航在颤动中返回到同一页面
- python - 无法在python中下载graphics.py
- python - 熊猫:对列求和,直到在其他列中满足条件
- javascript - 如何用 React 组件、react-router-dom 链接或锚标记替换位或字符串
- shopify - 使用 Liquid 将下拉框中的项目大写
- python-3.x - 使用特征和邻接矩阵的 numpy 表示构建 networkx/dgl 图
- r - 如何创建一个基于 R 中的条件重置的新变量
- javascript - 以正确的方式从 Firebase 获取所有集合数据
- questdb - 将 Influx 线路协议与 QuestDb 一起使用时出现重复记录