Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitff25a41

Browse files
committed
Singleton improvements
1 parent3dfec60 commitff25a41

File tree

2 files changed

+68
-63
lines changed

2 files changed

+68
-63
lines changed

‎src/Singleton/Conceptual/NonThreadSafe/main.py‎

Lines changed: 14 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -15,44 +15,26 @@
1515
fromtypingimportOptional
1616

1717

18-
classSingleton:
18+
classSingletonMeta(type):
1919
"""
20-
EN: The Singleton classdefines the `get_instance` method that serves as
21-
an alternative to constructor and lets clients access the same instance
22-
of this class over and over.
20+
EN: The Singleton classcan be implemented in different ways in Python. Some
21+
possible methods include: base class, decorator, metaclass. We will use the
22+
metaclass because it is best suited for this purpose.
2323
24-
RU:Класс Одиночка предоставляет метод `get_instance`, который ведёт себя
25-
как альтернативный конструктор и позволяет клиентам получать один и тот
26-
же экземпляр класса при каждом вызове.
24+
RU:В Python класс Одиночка можно реализовать по-разному. Возможные
25+
способы включают себя базовый класс, декоратор, метакласс. Мы воспользуемся
26+
метаклассом, поскольку он лучше всего подходит для этой цели.
2727
"""
2828

2929
_instance:Optional[Singleton]=None
3030

31-
def__init__(self)->None:
32-
ifSingleton._instanceisnotNone:
33-
raiseReferenceError("Cannot instantiate a singleton class.")
34-
else:
35-
Singleton._instance=self
31+
def__call__(self)->Singleton:
32+
ifself._instanceisNone:
33+
self._instance=super().__call__()
34+
returnself._instance
3635

37-
@staticmethod
38-
defget_instance()->Singleton:
39-
"""
40-
EN: The static method that controls the access to the singleton
41-
instance.
42-
43-
This implementation let you subclass the Singleton class while keeping
44-
just one instance of each subclass around.
45-
46-
RU: Статический метод, управляющий доступом к экземпляру одиночки.
47-
48-
Эта реализация позволяет вам расширять класс Одиночки, сохраняя повсюду
49-
только один экземпляр каждого подкласса.
50-
"""
51-
52-
ifnotSingleton._instance:
53-
Singleton()
54-
returnSingleton._instance
5536

37+
classSingleton(metaclass=SingletonMeta):
5638
defsome_business_logic(self):
5739
"""
5840
EN: Finally, any singleton should define some business logic, which can
@@ -70,8 +52,8 @@ def some_business_logic(self):
7052
#
7153
# RU: Клиентский код.
7254

73-
s1=Singleton.get_instance()
74-
s2=Singleton.get_instance()
55+
s1=Singleton()
56+
s2=Singleton()
7557

7658
ifid(s1)==id(s2):
7759
print("Singleton works, both variables contain the same instance.")

‎src/Singleton/Conceptual/ThreadSafe/main.py‎

Lines changed: 54 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -16,45 +16,70 @@
1616
fromtypingimportOptional
1717

1818

19-
classSingleton:
19+
classSingletonMeta(type):
2020
"""
21-
EN: The Singleton class defines the `getInstance` method that lets clients
22-
access the unique singleton instance.
21+
EN: This is a thread-safe implementation of Singleton.
2322
24-
RU: Класс Одиночка предоставляет метод getInstance, который позволяет
25-
клиентам получить доступ к уникальному экземпляру одиночки.
23+
RU: Это потокобезопасная реализация класса Singleton.
2624
"""
2725

2826
_instance:Optional[Singleton]=None
2927

3028
_lock:Lock=Lock()
29+
"""
30+
We now have a lock object that will be used to synchronize
31+
threads during first access to the Singleton.
32+
33+
RU: У нас теперь есть объект-блокировка для синхронизации потоков во
34+
время первого доступа к Одиночке.
35+
"""
3136

32-
value:str
33-
37+
def__call__(cls,*args,**kwargs):
38+
# EN: Now, imagine that the program has just been launched.
39+
# Since there's no Singleton instance yet, multiple threads can
40+
# simultaneously pass the previous conditional and reach this
41+
# point almost at the same time. The first of them will acquire
42+
# lock and will proceed further, while the rest will wait here.
43+
#
44+
# RU: Теперь представьте, что программа была только-только
45+
# запущена. Объекта-одиночки ещё никто не создавал, поэтому
46+
# несколько потоков вполне могли одновременно пройти через
47+
# предыдущее условие и достигнуть блокировки. Самый быстрый
48+
# поток поставит блокировку и двинется внутрь секции, пока
49+
# другие будут здесь его ожидать.
50+
withcls._lock:
51+
# EN: The first thread to acquire the lock, reaches this
52+
# conditional, goes inside and creates the Singleton
53+
# instance. Once it leaves the lock block, a thread that
54+
# might have been waiting for the lock release may then
55+
# enter this section. But since the Singleton field is
56+
# already initialized, the thread won't create a new
57+
# object.
58+
#
59+
# RU: Первый поток достигает этого условия и проходит внутрь,
60+
# создавая объект-одиночку. Как только этот поток покинет
61+
# секцию и освободит блокировку, следующий поток может
62+
# снова установить блокировку и зайти внутрь. Однако теперь
63+
# экземпляр одиночки уже будет создан и поток не сможет
64+
# пройти через это условие, а значит новый объект не будет
65+
# создан.
66+
ifnotcls._instance:
67+
cls._instance=super().__call__(*args,**kwargs)
68+
returncls._instance
69+
70+
71+
classSingleton(metaclass=SingletonMeta):
72+
value:str=None
73+
"""
74+
EN: We'll use this property to prove that our Singleton really works.
75+
76+
RU: Мы используем это поле, чтобы доказать, что наш Одиночка
77+
действительно работает.
78+
"""
79+
3480
def__init__(self,value:str)->None:
3581
self.value=value
3682

37-
@staticmethod
38-
defget_instance(value:str)->Singleton:
39-
"""
40-
EN: The static method that controls the access to the singleton
41-
instance.
42-
43-
This implementation let you subclass the Singleton class while keeping
44-
just one instance of each subclass around.
45-
46-
RU: Статический метод, управляющий доступом к экземпляру одиночки.
47-
48-
Эта реализация позволяет вам расширять класс Одиночки, сохраняя повсюду
49-
только один экземпляр каждого подкласса.
50-
"""
51-
52-
ifnotSingleton._instance:
53-
withSingleton._lock:
54-
ifnotSingleton._instance:
55-
Singleton._instance=Singleton(value)
56-
returnSingleton._instance
57-
5883
defsome_business_logic(self):
5984
"""
6085
EN: Finally, any singleton should define some business logic, which can
@@ -64,11 +89,9 @@ def some_business_logic(self):
6489
которая может быть выполнена на его экземпляре.
6590
"""
6691

67-
# ...
68-
6992

7093
deftest_singleton(value:str)->None:
71-
singleton=Singleton.get_instance(value)
94+
singleton=Singleton(value)
7295
print(singleton.value)
7396

7497

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp