Подтвердить что ты не робот

Могу ли я динамически преобразовывать экземпляр одного класса в другой?

У меня есть класс, описывающий шахматные фигуры. Я делаю для всех типов в Board класс, например, пешку, королеву, остроумие и т.д. У меня проблемы с классом Pawn. Я хочу преобразовать в Queen или другой объект, у которого есть класс (когда пешка переходит к восьмой строке, а затем конвертируется в что-то другое), как я могу это сделать?

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")
4b9b3361

Ответ 1

На самом деле можно назначить self.__class__ в Python, но вам действительно нужно знать, что вы делаете. Эти два класса должны быть в некотором роде совместимы (оба являются определяемыми пользователем классами, оба - как в стиле старого, так и в новом стиле, и я не уверен в использовании __slots__). Кроме того, если вы выполняете pawn.__class__ = Queen, объект пешки не будет создан конструктором Queen, поэтому ожидаемые атрибуты экземпляра могут отсутствовать и т.д.

Альтернативой будет такой тип конструктора копирования, как это:

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

Изменить: см. также Присвоение атрибуту __class__ экземпляра в Python

Ответ 2

Объект в Python всегда будет экземпляром его класса. Невозможно изменить это, не прибегая к "грязным хакам".

В вашем случае вы, вероятно, должны рассмотреть возможность реорганизации логики. Вместо того, чтобы позволить кусочку двигаться самостоятельно, определите какой-то контроллер, который перемещает куски. Если пешка достигает последней строки, этот контроллер может легко заменить кусок другим.

Ответ 3

Один из способов решить этот вопрос - иметь общий 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)

Ответ 4

Одним из решений может быть разрешение Pawn, например. на Pawn.promote_to('Q'), верните Королеву так, чтобы piece = piece.update() был бы разумным в любом случае.