Могу ли я динамически преобразовывать экземпляр одного класса в другой?
У меня есть класс, описывающий шахматные фигуры. Я делаю для всех типов в 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")
Ответы
Ответ 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()
был бы разумным в любом случае.