Pool of hashable objects

I made a very recursive, hashing (assumed immutable) data structure. Thus, it would be nice to have only one instance of each object (if objectA == objectB

, then there is no reason not to objectA is objectB

).

I tried to solve it by specifying a custom one __new__()

. It creates the requested object, then checks if it is in the dictionary (stored as a class variable). The object is added to the dict if necessary and then returned. If it's already in the dict, the version in the dict is returned and the newly created instance goes out of scope.

This solution works, but

  • I must have a dict where value

    in each key

    is the same object. I really need to retrieve an object from a set when I "show" a set of an equal object. Is there a more elegant way to do this?
  • Is there a built-in / canonical solution to my problem in Python? Such as the class that I inherit or something ...

My current implementation runs along the following lines:

class NoDuplicates(object):
    pool = dict()
    def __new__(cls, *args):
        new_instance = object.__new__(cls)
        new_instance.__init__(*args)
        if new_instance in cls.pool:
            return cls.pool[new_instance]
        else:
            cls.pool[new_instance] = new_instance
            return new_instance

      

I am not a programmer by profession, so I suspect this is in line with a known technique or concept. The most similar concepts that come to mind are memoization and singleton.

One subtle issue with the above implementation is that __init__

it is always called on the return value from __new__

. I made a metaclass to change this behavior. But it ended up causing a lot of trouble as it NoDuplicates

also inherits from dict

.

+3


source to share


1 answer


First, I would use a factory instead of overriding __new__

. See Using Python __new__ and __init__? ...



Second, you can use the tuples of the arguments needed to create the object as dictionary keys (assuming the same arguments yield the same objects, of course), so you don't have to create an actual (expensive to create) instance of the object.

+2


source







All Articles