Singleton is a creational design pattern, which ensures that only one object of its kind exists and provides a single point of access to it for any other code.
Singleton is alike to the global variable.
Code
class SingletonMeta(type):
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
instance = super().__call__(*args, **kwargs)
cls._instances[cls] = instance
return cls._instances[cls]
class Singleton(metaclass=SingletonMeta):
pass
There are several ways to implement the singleton pattern.
Therefore, of course, You can use different methods.
Test
s1 = Singleton()
s2 = Singleton()
if s1 is s2:
print("Same")
else:
print("different")
# Same
It works well.
Usage
Now, let's use this singleton pattern with business logic.
class Singleton(metaclass=SingletonMeta):
def __init__(self, num: int) -> None:
self.num = num
def increase(self) -> None:
self.num += 1
s1 = Singleton(0)
s2 = Singleton(0)
s1.increase()
s2.increase()
print(s1.num) # 2
print(s2.num) # 2
The instance with the initial value is returned when firstly called, and the same instance is returned when called again.
Play with this example!
Thread-Safe Code
Let's change the singleton to thread-safe.
from threading import Lock
class SingletonMeta(type):
_instances = {}
_lock: Lock = Lock()
def __call__(cls, *args, **kwargs):
with cls._lock:
if cls not in cls._instances:
instance = super().__call__(*args, **kwargs)
cls._instances[cls] = instance
return cls._instances[cls]
class Singleton(metaclass=SingletonMeta):
pass
Let's use it with threads.
from threading import Lock, Thread
class Singleton(metaclass=SingletonMeta):
def __init__(self, num: int) -> None:
self.num = num
def increase(self) -> None:
self.num += 1
def test_singleton(num: int) -> None:
singleton = Singleton(num)
print("before: ",singleton.num)
singleton.increase()
print("after: ",singleton.num)
process1 = Thread(target=test_singleton, args=(2, ))
process2 = Thread(target=test_singleton, args=(7, ))
process1.start()
process2.start()
# before: 2
# after: 3
# before: 3
# after: 4
Great!
Feel free to use this awesome stuff.
'Python' 카테고리의 다른 글
[Python] finterstellar를 사용하여 MACD로 주식 매매 시그널 만들기 (0) | 2021.12.10 |
---|---|
[Python] finterstellar를 사용하여 RSI로 주식 매매 시그널 만들기 (0) | 2021.12.09 |
[Python] String (0) | 2021.10.31 |
[Python] Testing (0) | 2021.10.30 |
[Python] Debugging (0) | 2021.10.27 |
댓글