gpt4 book ai didi

python - 改变对象的类

转载 作者:行者123 更新时间:2023-12-01 07:58:04 25 4
gpt4 key购买 nike

在国际象棋游戏中,我定义p1 = Pawn()

我希望能够推广它:

def promote(self, piece):
pos = f'{Config.tile_convert(self.x)}{Config.tile_convert(self.y, True)}'
try:
self = piece(pos, color=self.color, num='s')
except NameError:
print(f'Cannot promote {self.pieceid} to {piece}')

但是,喂入 QueenBishop 实际上并不会改变对象的 Pawn 状态。我认为这是因为范围界定:

class Chesspiece:
...

class Pawn(ChessPiece):
def promote()
...

class Queen(Chesspiece):
...

如何更改对象的类?

最佳答案

重新分配任何裸名称(包括self)重新绑定(bind)名称;之前里面的东西都被扔掉了,而且这个名字现在指向了一些不相关的东西。

所以当你这样做时:

self = piece(pos, color=self.color, num='s')

您只是失去了对“真实”self(调用该方法的对象)的访问权限,您无法更改调用它的对象。

做你想做的事情的唯一方法有点hacky;重新分配 self 上的 __class__ (并更改使其成为新类的有效实例所需的任何其他属性)。

因此在这种情况下,您可能可以这样做:

self.__class__ = piece

如果属性值可能需要重新创建/重新验证,或者piece可能是一个工厂函数或奇怪的类,其__new__不一定返回它原来的类型调用时,您将创建一个新片段作为模板,然后从中复制,如下所示:

# Make a new piece to copy from
newpiece = piece(pos, color=self.color, num='s')

vars(self).clear() # Clear out existing attributes
vars(self).update(vars(newpiece)) # Copy attributes from new piece
self.__class__ = newpiece.__class__ # Using newpiece.__class__ ensures it's the resulting class
# in case of factory functions, weird __new__, etc.

注意:这通常不是您想要做的事情。如Rocky Li mentions in the comments ,通常的方法是替换包含它的任何结构中的对象,而不是更新现有对象上的类,例如如果您有名为 board 的变量,它是列表的二维列表,您只需执行以下操作:

a_piece = ...  # Piece to replace
new_piece_type = ... # Type of piece it's being replaced with
pos = f'{Config.tile_convert(a_piece.x)}{Config.tile_convert(a_piece.y, True)}'

# Replace entire object (and local alias name) at known coordinates with new object
board[a_piece.x][a_piece.y] = a_piece = new_piece_type(pos, color=a_piece.color, num='s')

关于python - 改变对象的类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55856272/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com