import logging
logger = logging.getLogger('NuRadioReco.metaclasses')
[docs]
class Singleton(type):
"""
Can be assigned to classes as a metaclass.
By default, only one instance of a Singleton can exist at a time,
as the ``__call__`` method is overwritten to
return the existing instance if one exists.
"""
_instances = {}
_args_kwargs = {}
def __call__(cls, *args, **kwargs):
"""
Overwrites the __call__ method
Checks if an instance of the class already exists
and returns that instance instead of creating a new one, unless
``create_new=True`` is specified.
Parameters
----------
create_new: bool (default: False)
If set to true, a new instance will always be created, even if one already exists.
"""
create_new = kwargs.pop('create_new', False)
if Singleton._instances.get(cls, None) is None or create_new:
Singleton._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
Singleton._args_kwargs[cls] = (args, kwargs)
elif (args, kwargs) != Singleton._args_kwargs[cls]:
msg = (
f'Singleton class {cls} was already initialized with different arguments. '
'To create a new instance with different initial values, include '
'`create_new=True` in the class initialization call.'
)
raise ValueError(msg)
return Singleton._instances[cls]