Is it safe to replace a self object by another object of the same type in a method?
It is unlikely that replacing the 'self' variable will accomplish whatever you're trying to do, that couldn't just be accomplished by storing the result of func(self) in a different variable. 'self' is effectively a local variable only defined for the duration of the method call, used to pass in the instance of the class which is being operated upon. Replacing self will not actually replace references to the original instance of the class held by other objects, nor will it create a lasting reference to the new instance which was assigned to it.
python - Can you replace an object completely by internal method?
self
is just another variable. Method objects cause the current instance to be assigned to that name (just like other values are assigned to other function parameters), but like other names, assigning to them will only change what object the name refers to. Other names that reference the same object, like x
, do not change along.
That's because names in Python code are just like tags, and self = <something else>
is like taking the tag of the old instance and putting it on another object. Any other tags still attached to the old object are not moved! Because x
still references the old instance, it is not going to see that you put the self
tag on another object.
Either your update()
method needs to return the new object (so that the caller can update their reference to point to the new object), or change the list in-place (at which point all references to the object will see the same change.
Returning the object means the caller is responsible for doing something with the return value:
class test(list):
def update(self):
return test(['a','b','c','d'])
x = test([1,2,3])
x = x.update() # re-bind `x` to point to the new object.
print(x)
Or you can assign to indices of the list itself; this changes what the contents of the list point to. You can use self
just like any other reference, so x[0] = 5
would change index 0, so would self[0] = 5
. And if you assign to a slice you can change multiple indices at once. The identity slice, [:]
, lets you change all indices at once, and you can assign more or fewer values to grow or shrink a list. Assigning to self[:]
changes all indices, and lets you change all indices to point to any number of different values.
So:
class test(list):
def update(self):
self[:] = ['a', 'b', 'c', 'd']
x = test([1,2,3])
x.update()
print(x) # The x reference to the same list will see the change too
The above replaces all indices with the values in the other list. All references to the instance will see the change; both as self
and x
, and any other such references.
Demo of what this means:
>>> class test(list):
... def update(self):
... self[:] = ['a', 'b', 'c', 'd']
...
>>> x = test([1, 2, 3])
>>> y = x # another reference to the same object
>>> x
[1, 2, 3]
>>> y
[1, 2, 3]
>>> x.update() # update the list in-place
>>> x # visible here
['a', 'b', 'c', 'd']
>>> y # and here!
['a', 'b', 'c', 'd']
is it possible to overwrite self to point to another object inside self.method 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.)
Can I replace an existing method of an object in Python?
Using some tips from:
Is it possible to change an instance's method implementation without changing all other instances of the same class?
you can do the following, by using the types module to assign a method to the object created without affecting the class. You need to do this because a function does not automatically receive the self object as the first variable, but a method does.
import types
joe = Person()
bob = Person()
joe.SayHi()
>>> Hello!
def greedy_has_good_mood(self):
return self.Cash > 100
joe.HasGoodMood = types.MethodType(greedy_has_good_mood, joe)
joe.SayHi()
>>> Hmpf.
bob.SayHi()
>>> Hello!
how to assign self to another instance of itself
A solution:
import copy
class TestClass:
def __init__(self, value):
if isinstance(value, TestClass):
self.__dict__ = copy.deepcopy(value.__dict__)
else:
self.data = value
This makes your example working. You want to do a 'copy constructor',
in Python objects have a __dict__
attribute containing all
members so you can just copy the dictionary from the original object
and assign it to the new object __dict__
.
Replace Instance of an object in python
I think a class method probably makes the most sense, something like
class Dictionary:
def __init__(self, collection_size):
self.dictionary = [Term() for _ in range(collection_size)]
self.collection_size = collection_size
@classmethod
def load_from_pickle(cls, src):
with open(src, 'rb') as handle:
cls = pickle.load(handle)
return cls
loaded_dictionary = Dictionary.load_from_pickle('path/to/pickle')
You probably want some "guardrails" on the load method to make sure you're unpickling an object that works.
At some point, you may also want some kind of Dictionary.merge, but that seems independent of initializing from a pickled object.
How do I use one object from one function in another function in the same class
The point of local variables is that they only exist within the function, so you can't do this by definition.
Often, the answer is to pass the variable's value around. For example, browse_file
could return img
to its caller, and that caller could keep it around and then pass it into grey_scale
later.
Another option is to use a class to hold state. These functions seems to be methods of a class already (based on the self
parameter), so there's a good chance this is the right design here. Just replace every img
in both functions with self.img
, and now this isn't a local variable, it's a member of the instance. Every method called on the same instance will have access to the same value. But if you create multiple instances of the same class, each instance will have its own img
.
Related Topics
Libxml Install Error Using Pip
Is a Python Dictionary an Example of a Hash Table
Regular Expression to Extract Url from an HTML Link
Combine Lists with Common Elements
How to Determine the Language of a Piece of Text
How to Put Multiple Statements in One Line
How to Have Assignment in a Condition
Pygame.Error: Video System Not Initialized
What's the Difference Between %S and %D in Python String Formatting
Why Doesn't a Python Dict.Update() Return the Object
How to Scroll Frame Using Mouse Wheel & Adding Horizontal Scrollbar
How to Change Default Anaconda Python Environment
Calculate Mean Across Dimension in a 2D Array