class Wrapper(object):
def __init__(self, o):
# get wrapped object and do something with it
self.o = o
def fun(self, *args, **kwargs):
self = self.o # here want to swap
# or some low level C api like
# some_assign(self, self.o)
# so that it swaps id() mem addr to self.o
return self.fun(*args, **kwargs) # and now it's class A
class A(object):
def fun(self):
return 'A.fun'
a = A()
w = Wrapper(a)
print(type(w)) # wrapper
print(w.fun()) # some operation after which I want to loose Wrapper
print(a is w) # this goes False and I'd like True :)
# so that this is the original A() object
Is there any way to do this in Python?
Assigning to self
inside a method simply rebinds the local variable self
to the new object. Generally, an assignment to a bare name never changes any objects, it just rebinds the name on the left-hand side to point to the object on the right-hand side.
So what you would need to do is modify the object self
points to to match the object self.o
points to. This is only possible if both A
and Wrapper
are new-style classes and none of them defines __slots__
:
self.__class__ = self.o.__class__
self.__dict__ = self.o.__dict__
This will work in CPython, but I'm not sure about the other Python implementation. And even in CPython, it's a terrible idea to do this.
(Note that the is
condition in the last line of your code will still be False
, but I think this does what you intend.)