Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

is it possible to overwrite "self" to point to another object inside self.method in python?

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?

like image 627
pprzemek Avatar asked Oct 29 '11 17:10

pprzemek


People also ask

Can self be replaced in Python?

self is only a reference to the current instance within the method. You can't change your instance by setting self . Save this answer.

How do you override an object in Python?

In Python method overriding occurs by simply defining in the child class a method with the same name of a method in the parent class. When you define a method in the object you make this latter able to satisfy that method call, so the implementations of its ancestors do not come in play.

What happens when you return self in Python?

return self would return the object that the method was called from.

Is self in Python a pointer?

That variable p points to a Point object (remember variables are pointers in Python). That self variable in our method call points to the same exact object. So self is really just a variable that points to the instance of our class that we're currently working with.


1 Answers

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.)

like image 150
Sven Marnach Avatar answered Jan 04 '23 20:01

Sven Marnach