22EN: Singleton Design Pattern
33
44Intent: Lets you ensure that a class has only one instance, while providing a
5- global access point to this instance.
5+ global access point to this instance. One instance per each subclass (if any).
66
77RU: Паттерн Одиночка
88
99Назначение: Гарантирует, что у класса есть только один экземпляр, и
10- предоставляет к нему глобальную точку доступа.
10+ предоставляет к нему глобальную точку доступа. У каждого наследника класса тоже
11+ будет по одному экземпляру.
1112"""
1213
13-
14- from __future__ import annotations
1514from threading import Lock , Thread
16- from typing import Optional
1715
1816
1917class SingletonMeta (type ):
@@ -23,7 +21,7 @@ class SingletonMeta(type):
2321 RU: Это потокобезопасная реализация класса Singleton.
2422 """
2523
26- _instance : Optional [ Singleton ] = None
24+ _instances = {}
2725
2826 _lock : Lock = Lock ()
2927 """
@@ -35,6 +33,13 @@ class SingletonMeta(type):
3533 """
3634
3735 def __call__ (cls , * args , ** kwargs ):
36+ """
37+ EN: Possible changes to the value of the `__init__` argument do not
38+ affect the returned instance.
39+
40+ RU: Данная реализация не учитывает возможное изменение передаваемых
41+ аргументов в `__init__`.
42+ """
3843 # EN: Now, imagine that the program has just been launched.
3944 # Since there's no Singleton instance yet, multiple threads can
4045 # simultaneously pass the previous conditional and reach this
@@ -63,9 +68,10 @@ def __call__(cls, *args, **kwargs):
6368 # экземпляр одиночки уже будет создан и поток не сможет
6469 # пройти через это условие, а значит новый объект не будет
6570 # создан.
66- if not cls ._instance :
67- cls ._instance = super ().__call__ (* args , ** kwargs )
68- return cls ._instance
71+ if cls not in cls ._instances :
72+ instance = super ().__call__ (* args , ** kwargs )
73+ cls ._instances [cls ] = instance
74+ return cls ._instances [cls ]
6975
7076
7177class Singleton (metaclass = SingletonMeta ):
@@ -101,7 +107,8 @@ def test_singleton(value: str) -> None:
101107 # RU: Клиентский код.
102108
103109 print ("If you see the same value, then singleton was reused (yay!)\n "
104- "If you see different values, then 2 singletons were created (booo!!)\n \n "
110+ "If you see different values, "
111+ "then 2 singletons were created (booo!!)\n \n "
105112 "RESULT:\n " )
106113
107114 process1 = Thread (target = test_singleton , args = ("FOO" ,))
0 commit comments