(How) Is it possible in Python to treat an instance of class B
exactly as an instance of class A
, where A
is a parent of B
(like up-casting in compiled languages)?
Say we have the following:
class A:
def __init__(self, prop=None):
self.prop = prop
def f(self):
return 'A.f'
def g(self):
return 'A.g', self.f()
class B(A):
def f(self):
return 'B.f'
def g(self):
return 'B.g', self.f()
Calling A().g()
produces ('A.g', 'A.f')
, whereas B().g()
produces ('B.g', 'B.f')
. Calling super(B, B()).g()
produces ('A.g', 'B.f')
, which is different from compiled languages, so I cannot use super
. Instead, I need a function that changes the type from which an instance's methods are resolved, but preserves (a reference to) the original state. In short, I'm looking for a way to do this:
b = B(object())
a = upcast(b, A)
a.prop = object()
assert isinstance(a, A)
assert a.g() == ('A.g', 'A.f')
assert a.prop is b.prop
The closest I could get is
a = copy.copy(b)
a.__class__ = A
a.__dict__ = b.__dict__
(assuming A/B
are "nice" "heap" classes), but this makes unnecessary copies of all objects in the __dict__
before I discard them. Is there a better way to do this?