Total Complexity | 2 |
Total Lines | 48 |
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 | ... self.objects = {} |
||
17 | |||
18 | >>> reg1 = ObjectDict() |
||
19 | >>> reg1.objects['a'] = 1 |
||
20 | |||
21 | >>> reg2 = ObjectRegistry() |
||
22 | >>> reg2.objects['b'] = 2 |
||
23 | |||
24 | >>> reg3 = ObjectRegistry() |
||
25 | |||
26 | |||
27 | >>> reg2.objects == {'a': 1} |
||
28 | True |
||
29 | |||
30 | >>> reg3.objects['a'] == 1 |
||
31 | True |
||
32 | |||
33 | >>> reg3.objects['b'] == 2 |
||
34 | True |
||
35 | |||
36 | >>> id(reg1) == id(reg2) == id(reg3) |
||
37 | True |
||
38 | """ |
||
39 | |||
40 | _instances: t.Mapping[t.Type, t.Any] = {} |
||
41 | |||
42 | def __call__(cls: t.Type, *args, **kwargs) -> t.Any: |
||
43 | instance = cls._instances.get(cls) |
||
44 | if not instance: |
||
45 | instance = super(Singleton, cls).__call__(*args, **kwargs) |
||
46 | cls._instances[cls] = instance |
||
47 | return instance |
||
48 |