싱글턴 패턴은 일반적으로 사용되는 소프트웨어 디자인 패턴입니다. 이 패턴의 주요 목적은 특정 클래스의 인스턴스가 하나만 존재하도록 하는 것입니다. 싱글톤 개체는 특정 클래스의 인스턴스 하나만 전체 시스템에 나타나도록 하려는 경우 유용합니다.
예를 들어 서버 프로그램의 구성 정보는 파일에 저장되며 클라이언트는 AppConfig 클래스를 통해 구성 파일 정보를 읽습니다. 프로그램을 실행하는 동안 구성 파일의 내용을 여러 위치에서 사용해야 하는 경우, 즉 AppConfig 개체의 인스턴스를 여러 위치에서 생성해야 하므로 여러 AppConfig 인스턴스 개체가 존재하게 됩니다. 이는 특히 구성 파일에 많은 콘텐츠가 포함된 경우 메모리를 심각하게 낭비하게 됩니다.
실제로 AppConfig와 같은 클래스의 경우 프로그램 실행 중에 인스턴스 개체가 하나만 존재하기를 바랍니다. Python에서는 싱글 톤 패턴을 구현하기 위해 다양한 방법을 사용할 수 있습니다.
모듈을 사용하여
그래서 싱글톤 객체를 얻으려면 모듈에서 관련 함수와 데이터만 정의하면 됩니다.
class Singleton(object): def foo(self): pass singleton = Singleton()
위 코드를 mysingleton.py 파일에 저장하세요. 사용하려면 이 파일의 개체를 다른 파일로 직접 가져오세요. 객체는 싱글턴 모드의 객체입니다
from mysingleton import singleton
데코레이터 사용하기
def Singleton(cls): _instance = {} def _singleton(*args, **kargs): if cls not in _instance: _instance[cls] = cls(*args, **kargs) return _instance[cls] return _singleton @Singleton class A(object): a = 1 def __init__(self, x=0): self.x = x a1 = A(2) a2 = A(3)
클래스 사용하기
class Singleton(object): def __init__(self): pass @classmethod def instance(cls, *args, **kwargs): if not hasattr(Singleton, "_instance"): Singleton._instance = Singleton(*args, **kwargs) return Singleton._instance
class Singleton(object): def __init__(self): pass @classmethod def instance(cls, *args, **kwargs): if not hasattr(Singleton, "_instance"): Singleton._instance = Singleton(*args, **kwargs) return Singleton._instance import threading def task(arg): obj = Singleton.instance() print(obj) for i in range(10): t = threading.Thread(target=task,args=[i,]) t.start()
<__main__.Singleton object at 0x02C933D0> <__main__.Singleton object at 0x02C933D0> <__main__.Singleton object at 0x02C933D0> <__main__.Singleton object at 0x02C933D0> <__main__.Singleton object at 0x02C933D0> <__main__.Singleton object at 0x02C933D0> <__main__.Singleton object at 0x02C933D0> <__main__.Singleton object at 0x02C933D0> <__main__.Singleton object at 0x02C933D0> <__main__.Singleton object at 0x02C933D0>
def __init__(self): import time time.sleep(1)프로그램을 다시 실행한 후 결과는 다음과 같습니다.
<__main__.Singleton object at 0x034A3410> <__main__.Singleton object at 0x034BB990> <__main__.Singleton object at 0x034BB910> <__main__.Singleton object at 0x034ADED0> <__main__.Singleton object at 0x034E6BD0> <__main__.Singleton object at 0x034E6C10> <__main__.Singleton object at 0x034E6B90> <__main__.Singleton object at 0x034BBA30> <__main__.Singleton object at 0x034F6B90> <__main__.Singleton object at 0x034E6A90>문제가 발생합니다! 위와 같은 방식으로 생성된 싱글톤은 멀티스레딩을 지원할 수 없습니다.
import time import threading class Singleton(object): _instance_lock = threading.Lock() def __init__(self): time.sleep(1) @classmethod def instance(cls, *args, **kwargs): with Singleton._instance_lock: if not hasattr(Singleton, "_instance"): Singleton._instance = Singleton(*args, **kwargs) return Singleton._instance def task(arg): obj = Singleton.instance() print(obj) for i in range(10): t = threading.Thread(target=task,args=[i,]) t.start() time.sleep(20) obj = Singleton.instance() print(obj)인쇄된 결과는 다음과 같습니다.
<__main__.Singleton object at 0x02D6B110> <__main__.Singleton object at 0x02D6B110> <__main__.Singleton object at 0x02D6B110> <__main__.Singleton object at 0x02D6B110> <__main__.Singleton object at 0x02D6B110> <__main__.Singleton object at 0x02D6B110> <__main__.Singleton object at 0x02D6B110> <__main__.Singleton object at 0x02D6B110> <__main__.Singleton object at 0x02D6B110> <__main__.Singleton object at 0x02D6B110>거의 다 끝났지만 여전히 작은 문제가 있습니다. 즉, 프로그램이 실행될 때 time.sleep(20)이 실행된 후 아래 개체가 인스턴스화될 때입니다. , 이는 이미 싱글톤 패턴입니다.
@classmethod def instance(cls, *args, **kwargs): if not hasattr(Singleton, "_instance"): with Singleton._instance_lock: if not hasattr(Singleton, "_instance"): Singleton._instance = Singleton(*args, **kwargs) return Singleton._instance이렇게 하면 멀티스레딩을 지원할 수 있는 싱글톤 모드가 완성됩니다. +
import time import threading class Singleton(object): _instance_lock = threading.Lock() def __init__(self): time.sleep(1) @classmethod def instance(cls, *args, **kwargs): if not hasattr(Singleton, "_instance"): with Singleton._instance_lock: if not hasattr(Singleton, "_instance"): Singleton._instance = Singleton(*args, **kwargs) return Singleton._instance def task(arg): obj = Singleton.instance() print(obj) for i in range(10): t = threading.Thread(target=task,args=[i,]) t.start() time.sleep(20) obj = Singleton.instance() print(obj)이렇게 구현된 싱글톤 모드는 사용에 제한이 있습니다. 나중에 인스턴스화는 obj = Singleton.instance()를 통해 이루어져야 합니다.
__new__ 메소드를 기반으로
위의 예를 통해 싱글톤을 구현할 때 스레드 안전성을 보장하기 위해 내부 잠금을 추가해야 함을 알 수 있습니다.
객체를 인스턴스화할 때 먼저 클래스의 __new__ 메서드를 실행하고(작성하지 않으면 기본적으로 object.__new__가 호출됨) 객체를 인스턴스화한 다음 __init__ 메서드를 실행합니다. 이 객체는 초기화되므로 이를 기반으로 싱글톤 패턴을 구현할 수 있습니다.
import threading class Singleton(object): _instance_lock = threading.Lock() def __init__(self): pass def __new__(cls, *args, **kwargs): if not hasattr(Singleton, "_instance"): with Singleton._instance_lock: if not hasattr(Singleton, "_instance"): Singleton._instance = object.__new__(cls) return Singleton._instance obj1 = Singleton() obj2 = Singleton() print(obj1,obj2) def task(arg): obj = Singleton() print(obj) for i in range(10): t = threading.Thread(target=task,args=[i,]) t.start()
<__main__.Singleton object at 0x038B33D0> <__main__.Singleton object at 0x038B33D0> <__main__.Singleton object at 0x038B33D0> <__main__.Singleton object at 0x038B33D0> <__main__.Singleton object at 0x038B33D0> <__main__.Singleton object at 0x038B33D0> <__main__.Singleton object at 0x038B33D0> <__main__.Singleton object at 0x038B33D0> <__main__.Singleton object at 0x038B33D0> <__main__.Singleton object at 0x038B33D0> <__main__.Singleton object at 0x038B33D0> <__main__.Singleton object at 0x038B33D0>
관련지식:
例子: class Foo: def __init__(self): pass def __call__(self, *args, **kwargs): pass obj = Foo() # 执行type的 __call__ 方法,调用 Foo类(是type的对象)的 __new__方法,用于创建对象,然后调用 Foo类(是type的对象)的 __init__方法,用于对对象初始化。 obj()# 执行Foo的 __call__ 方法
class SingletonType(type): def __init__(self,*args,**kwargs): super(SingletonType,self).__init__(*args,**kwargs) def __call__(cls, *args, **kwargs): # 这里的cls,即Foo类 print('cls',cls) obj = cls.__new__(cls,*args, **kwargs) cls.__init__(obj,*args, **kwargs) # Foo.__init__(obj) return obj class Foo(metaclass=SingletonType): # 指定创建Foo的type为SingletonType def __init__(self,name): self.name = name def __new__(cls, *args, **kwargs): return object.__new__(cls) obj = Foo('xx')
import threading class SingletonType(type): _instance_lock = threading.Lock() def __call__(cls, *args, **kwargs): if not hasattr(cls, "_instance"): with SingletonType._instance_lock: if not hasattr(cls, "_instance"): cls._instance = super(SingletonType,cls).__call__(*args, **kwargs) return cls._instance class Foo(metaclass=SingletonType): def __init__(self,name): self.name = name obj1 = Foo('name') obj2 = Foo('name') print(obj1,obj2)
위 내용은 Python에서 싱글톤 모드를 구현하는 5가지 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!