Can I dynamically convert an instance of one class to another?

前端 未结 4 769
灰色年华
灰色年华 2020-12-03 07:37

I have a class that describe chess pieces. I make for all type piece in the Board a class for example Pawn, Queen, keen, etc... I have a trouble in Pawn class I want to conv

相关标签:
4条回答
  • 2020-12-03 07:39

    An object in Python will always be an instance of its class. There is no way to change that without resorting to "dirty hacks".

    In your case, you should probably consider refactoring the logic. Instead of letting a piece move itself, define some kind of controller that moves the pieces. If a pawn reaches the last row, this controller can easily replace a piece with another.

    0 讨论(0)
  • 2020-12-03 07:40

    One solution could be to let Pawn, via e.g. on Pawn.promote_to('Q'), return a Queen such that piece = piece.update() would be sensible in any case.

    0 讨论(0)
  • 2020-12-03 07:41

    One way to solve this is to have a generic Piece class and another Strategy or Characteristics class. The piece provides generic interface common to all pieces (like move_to, or something) and Strategy decides if it's possible and how to execute the command. When you want to change a pawn to a queen, you change the strategy of the piece.

    Edit: In your case it might not even be necessary to make it that complicated. You could have something like this:

    class Piece:
        def __init__(self, movefunc):
            self.move = movefunc
    
    def move_pawn(inst, unit=1):
        pass
    
    pawn = Piece(move_pawn)
    
    0 讨论(0)
  • 2020-12-03 08:00

    It is actually possible to assign to self.__class__ in Python, but you really have to know what you're doing. The two classes have to be compatible in some ways (both are user-defined classes, both are either old-style or new-style, and I'm not sure about the use of __slots__). Also, if you do pawn.__class__ = Queen, the pawn object will not have been constructed by the Queen constructor, so expected instance attributes might not be there etc.

    An alternative would be a sort of copy constructor like this:

    class ChessPiece(object):
      @classmethod
      def from_other_piece(cls, other_piece):
        return cls(other_piece.x, other_piece.y)
    

    Edit: See also Assigning to an instance's __class__ attribute in Python

    0 讨论(0)
提交回复
热议问题