インスタンスが属するクラスをあとから変更する操作を Python で

import math

class Cartesian:
  def __init__(self, x = 0, y = 0):
    self.x = x
    self.y = y

class Polar:
  def __init__(self, r = 0, theta = 0):
    self.r = r
    self.theta = theta

def cart2pol(x, y):
  return math.sqrt(x*x + y*y), math.atan2(y, x)

def pol2cart(r, theta):
  return r*math.cos(theta), r*math.sin(theta)

def transmogrify(a, b):
  a.__dict__, a.__class__ = b.__dict__, b.__class__

pos1 = pos2 = Polar(math.sqrt(2), math.pi/4)
pos1.__class__.__name__   #=> 'Polar'

transmogrify(pos1, Cartesian(*pol2cart(pos1.r, pos1.theta)))
pos1.__class__.__name__   #=> 'Cartesian'
pos1.x                    #=> 1.0000000000000002
pos1.y                    #=> 1.0
pos2.__class__.__name__   #=> 'Cartesian'

transmogrify(pos1, Polar(*cart2pol(pos1.x, pos1.y)))
pos1.__class__.__name__   #=> 'Polar'
pos1.r                    #=> 1.4142135623730951
pos1.theta/math.pi        #=> 0.24999999999999997


参考: