| Total Complexity | 2 |
| Total Lines | 49 |
| Duplicated Lines | 0 % |
| Changes | 0 | ||
| 1 | import typing as t |
||
| 2 | |||
| 3 | |||
| 4 | class Singleton(type): |
||
| 5 | """Singleton Design Pattern imlemented as a Metaclass. |
||
| 6 | |||
| 7 | Use this Metaclass to design your class (constructor) with the Singleton |
||
| 8 | Pattern. Setting your class's 'metaclass' key to this Metaclass (see |
||
| 9 | example below), will restrict object instantiation so that it always return |
||
| 10 | the same (singleton) object. |
||
| 11 | |||
| 12 | Example: |
||
| 13 | |||
| 14 | >>> class ObjectDict(metaclass=Singleton): |
||
| 15 | ... def __init__(self): |
||
| 16 | ... super().__init__() |
||
| 17 | ... self.objects = {} |
||
| 18 | |||
| 19 | >>> reg1 = ObjectDict() |
||
| 20 | >>> reg1.objects['a'] = 1 |
||
| 21 | |||
| 22 | >>> reg2 = ObjectRegistry() |
||
| 23 | >>> reg2.objects['b'] = 2 |
||
| 24 | |||
| 25 | >>> reg3 = ObjectRegistry() |
||
| 26 | |||
| 27 | |||
| 28 | >>> reg2.objects == {'a': 1} |
||
| 29 | True |
||
| 30 | |||
| 31 | >>> reg3.objects['a'] == 1 |
||
| 32 | True |
||
| 33 | |||
| 34 | >>> reg3.objects['b'] == 2 |
||
| 35 | True |
||
| 36 | |||
| 37 | >>> id(reg1) == id(reg2) == id(reg3) |
||
| 38 | True |
||
| 39 | """ |
||
| 40 | |||
| 41 | _instances: t.Mapping[t.Type, t.Any] = {} |
||
| 42 | |||
| 43 | def __call__(cls: t.Type, *args, **kwargs) -> t.Any: |
||
| 44 | instance = cls._instances.get(cls) |
||
| 45 | if not instance: |
||
| 46 | instance = super(Singleton, cls).__call__(*args, **kwargs) |
||
| 47 | cls._instances[cls] = instance |
||
| 48 | return instance |
||
| 49 |