Skip to content

Instantly share code, notes, and snippets.

@zynaxsoft
Last active March 2, 2020 05:31
Show Gist options
  • Save zynaxsoft/19f827b65ff8d9e4dcde384917dee3ac to your computer and use it in GitHub Desktop.
Save zynaxsoft/19f827b65ff8d9e4dcde384917dee3ac to your computer and use it in GitHub Desktop.
Yet another way to create a singleton in python
#############################
# descriptor version
# (only one class is supported currently)
#############################
class _Singleton:
def __set_name__(self, owner, name):
self.name = name
self.instance_created = False
def __set__(self, instance, value):
if not self.instance_created:
self.instance_created = True
instance.__instance = value
else:
raise AttributeError(
f'{instance.__name__} should not be'
f' created more than once.'
)
def __get__(self, instance, owner):
return instance.__instance
class Singleton(type):
_instance = _Singleton()
def __call__(cls, *args, **kwargs):
if '_instance' not in cls.__dict__:
cls._instance = super().__call__(*args, **kwargs)
return cls._instance
else:
raise AttributeError(
f'{cls.__name__} should not be created more than once.'
)
@property
def inst(cls):
return cls._instance
class Foo(metaclass=Singleton):
pass
#############################
# dict version
#############################
class Singleton(type):
_instance = {}
def __call__(cls, *args, **kwargs):
if cls.__name__ not in cls._instance:
cls._instance[cls.__name__] = super().__call__(*args, **kwargs)
return cls._instance[cls.__name__]
else:
raise AttributeError(
f'{cls.__name__} should not be created more than once.'
)
@property
def inst(cls):
return cls._instance[cls.__name__]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment