Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reuse existing objects for immutable objects?

In Python, how is it possible to reuse existing equal immutable objects (like is done for str)? Can this be done just by defining a __hash__ method, or does it require more complicated measures?

like image 209
Abbafei Avatar asked Mar 01 '11 22:03

Abbafei


People also ask

What is the advantage of reusing existing objects?

Advantages of reuse: You are not discarding as much memory, requires less garbage collection. You only need to update objects that have changed.

Can an immutable object be modified?

An immutable object cannot be modified after it was created. Immutable objects have two great advantages: Code based on immutable objects is clearer and likelier to be correct. Bugs involving unexpected changes simply can't occur.

How do you reuse an object in Java?

An object can always be reused if it is immutable (Item 15). As an extreme example of what not to do, consider this statement: String s = new String("stringette"); // DON'T DO THIS! The statement creates a new String instance each time it is executed, and none of those object creations is necessary.

What is the difference between mutability and immutability?

If the value can change, the object is called mutable, while if the value cannot change, the object is called immutable.


1 Answers

If you want to create via the class constructor and have it return a previously created object then you will need to provide a __new__ method (because by the time you get to __init__ the object has already been created).

Here is a simple example - if the value used to initialise has been seen before then a previously created object is returned rather than a new one created:

class Cached(object):
    """Simple example of immutable object reuse."""

    def __init__(self, i):
        self.i = i

    def __new__(cls, i, _cache={}):
        try:
            return _cache[i]
        except KeyError:
            # you must call __new__ on the base class
            x = super(Cached, cls).__new__(cls)
            x.__init__(i)
            _cache[i] = x
            return x

Note that for this example you can use anything to initialise as long as it's hashable. And just to show that objects really are being reused:

>>> a = Cached(100)
>>> b = Cached(200)
>>> c = Cached(100)
>>> a is b
False
>>> a is c
True
like image 140
Scott Griffiths Avatar answered Oct 03 '22 09:10

Scott Griffiths