Your code seems correct - the only thing that is incorrect above is that your __init__ method will always be called when creating an instance of a new class, regardless of the previous instance returned by __new__ or not.
So, if you create additional objects in your __init__ method, this may cause a memory leak, however, if you bind these new objects to instane (self), they shuld just redefine the previously created object in the same place - so that they are freed ., In the code here, this happens with self.name - perhaps your real __init__ does more things and associates new objects with other places than the instance (for example, assigning them to a list). If your __init__ methods are shown exactly the same, the reason for your memory growth is not obvious in the code you supply.
As an additional piece of advice, but not related to the problem you are linking, I add that you don't need a metaclass at all.
Just check for cls.instantiated_objects dict in the __new__ method __new__ . Without writing out an unnecessary metaclass, you simplify your code base, avoid metaclass conflicts if your class hierarchy develops, and can even end your problem if your metaclass has more code than shown here.
The __new__ base class __new__ can be rewritten like this:
class AdwordsObject(object): def __new__(cls, *args): if not cls.__dict__.get("instantiated_objects"): cls.instantiated_objects = {} name = '-'.join(args) if name in cls.instantiated_objects: return cls.instantiated_objects[name] instance = super().__new__(cls) cls.instantiated_objects[name] = instance return instance
And you no longer need a custom metaclass.
source share