Skip to content Skip to sidebar Skip to footer

Python Class Inherited Singleton Inits Instance On Every Call

I'm trying to implement class inherited singleton as described here (Method 2). Going over the question and the extensive chosen answer I tried to implement the following: class Si

Solution 1:

In modern Python this could be done by writting a __init_subclass__ method that could decorate __init__ to make it check cls._instance before running.

As it is, (i.e. you need it for Python 2 as well) - I think the simpler thing is for __new__ to patch __init__ with a NOP method if the instance already exists:


_nop_init = lambda self, *args, **kw: NoneclassSingleton(object):
    _instance = Nonedef__new__(cls, *args, **kwargs):
        ifnotisinstance(cls._instance, cls):
            cls._instance = object.__new__(cls, *args, **kwargs)
            cls._instance._initialized = False# Python 2 have to check in the cls.__dict__ - Py3 could check the attribute directly:elif cls.__dict__.get("__init__", None) isnot _nop_init:
            cls.__init__ = _nop_init
        return cls._instance

classA(Singleton):
    def__init__(self):
        print"Init is called"classB(Singleton):
    def__init__(self):
        print"Init is called"

extra info The language mechanism to call __init__ is built-in the __call__ method of type - the metaclass for all classes in Python. It will call the __new__ and __init__ method of a target class when instantiating it, and thus, with a metaclass, it is easy to control these calls from a custom metaclass. It is also interesting to note that when __new__ does not return an instance of the target class, __init__ is not called. (In this singleton case, the singleton is an instance of te class, and thus it is called).

real world example: last time I coded a singleton, I opted for avoiding re-run __init__ in its own code - sine it is the only singleton in the project, tere was no need for generic code for that in a __new__: https://github.com/jsbueno/pythonchain/blob/1f9208dc8bd2741a574adc1bf745d218e4314e4a/pythonchain/block.py#L276

Post a Comment for "Python Class Inherited Singleton Inits Instance On Every Call"