我可以动态地将一个类的实例转换为另一个类吗?

时间:2011-11-09 08:31:36

标签: python

我有一个描述棋子的课程。我为董事会中的所有类型制作了一个类,例如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")

4 个答案:

答案 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类和另一个StrategyCharacteristics类。该部分提供了所有部分共同的通用接口(如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到达最后一行,这个控制器可以很容易地用另一个替换一块。