我有一个描述棋子的课程。我为董事会中的所有类型制作了一个类,例如Pawn,Queen,keen等...... 我在Pawn类中遇到麻烦我想转换为Queen或其他具有类的对象(当pawn转到第8行然后转换为其他对象时)我该怎么做?
class Pawn:
def __init__(self ,x ,y):
self.x = x
self.y = y
def move(self ,unit=1):
if self.y ==7 :
self.y += 1
what = raw_input("queen/rook/knight/bishop/(Q,R,K,B)?")
# There is most be changed that may be convert to:
# Queen ,knight ,bishop ,rook
if self.y != 2 and unit == 2:
print ("not accesible!!")
elif self.y ==2 and unit == 2:
self.y += 2
elif unit == 1:
self.y += 1
else:
print("can`t move over there")
答案 0 :(得分:23)
实际上可以在Python中分配给self.__class__
,但你真的必须知道你在做什么。这两个类必须在某些方面兼容(两者都是用户定义的类,都是旧式或新式的,我不确定使用__slots__
)。此外,如果你执行pawn.__class__ = Queen
,pawn对象将不会由Queen构造函数构造,因此预期的实例属性可能不在那里等。
另一种选择是这样的复制构造函数:
class ChessPiece(object):
@classmethod
def from_other_piece(cls, other_piece):
return cls(other_piece.x, other_piece.y)
修改:另请参阅Assigning to an instance's __class__ attribute in Python
答案 1 :(得分:1)
解决此问题的一种方法是使用通用Piece
类和另一个Strategy
或Characteristics
类。该部分提供了所有部分共同的通用接口(如move_to
或其他内容),Strategy
决定是否可能以及如何执行命令。当你想把一个棋子改成一个女王时,你就改变了这个棋子的策略。
编辑:在你的情况下甚至可能没有必要使它变得那么复杂。你可以这样:
class Piece:
def __init__(self, movefunc):
self.move = movefunc
def move_pawn(inst, unit=1):
pass
pawn = Piece(move_pawn)
答案 2 :(得分:0)
一种解决方案可能是让Pawn
通过例如在Pawn.promote_to('Q')
上,返回一位女王,以便piece = piece.update()
在任何情况下都是明智的。
答案 3 :(得分:-1)
Python中的对象始终是其类的实例。如果不诉诸“肮脏的黑客”,就没有办法改变它。
在您的情况下,您应该考虑重构逻辑。而不是让一块自己移动,定义一种移动碎片的控制器。如果一个pawn到达最后一行,这个控制器可以很容易地用另一个替换一块。