Last active
March 2, 2020 05:31
-
-
Save zynaxsoft/19f827b65ff8d9e4dcde384917dee3ac to your computer and use it in GitHub Desktop.
Yet another way to create a singleton in python
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
############################# | |
# 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