>백엔드 개발 >파이썬 튜토리얼 >Python 싱글톤의 두 가지 구현 방법 소개(코드 포함)

Python 싱글톤의 두 가지 구현 방법 소개(코드 포함)

不言
不言앞으로
2018-10-12 15:37:002078검색

이 기사에서는 Python 싱글턴(코드 포함)의 두 가지 구현 방법을 소개합니다. 이는 특정 참조 가치가 있으므로 도움이 필요한 친구에게 도움이 되기를 바랍니다.

지난 이틀간 제가 예전에 작성한 코드를 살펴보며 일상적인 코드 작업에서 자주 사용하는 싱글톤 모드를 정리했습니다.

그래서 달라진 점은 다음과 같습니다. 예전에 사용했던 싱글톤 구현 방식을 정리해보자

데코레이터 방식

이 방식도 업무에서도 자주 사용하는데, 코드는 다음과 같이 구현하면 더 편리하다

def Singleton(cls):
    _instance = {}
    def _singleton(*args, **kwargs):
        if cls not in _instance:
            _instance[cls] = cls(*args, **kwargs)
        return _instance[cls]

    return _singleton

작동하는 경우 클래스가 싱글톤을 사용해야 하는 경우 다음과 유사한 방식으로 구현할 수 있습니다.

@Singleton
class A(object):    
def __init__(self, x):
     self.x = x

저는 개인적으로 이런 방식을 꽤 좋아합니다

클래스 방식으로 구현

실제로 여기에 주의해야 할 몇 가지 문제가 있습니다. 좋습니다. 먼저 가능한 오류 코드를 살펴보겠습니다

class Member(object):
    @classmethod
    def instance(cls, *args, **kwargs):
        if not hasattr(Member, "_instance"):
            Member._instance = Member(*args, **kwargs)
        return Member._instance

얼핏 보면 이 클래스는 싱글톤을 구현한 것처럼 보이지만 잠재적인 가능성이 있습니다. 즉, 멀티 스레드인 경우 이렇게 작성하면 문제가 발생합니다. 특히 현재 클래스의 초기화 개체에 시간이 많이 걸리는 작업이 있는 경우에는 다음 코드가 있습니다.

#! /usr/bin/env python3
# .-*- coding:utf-8 .-*-
import time
import threading
import random
class Member(object):
    def __init__(self):
        time.sleep(random.randint(1,3))
    @classmethod
    def instance(cls, *args, **kwargs):
        if not hasattr(Member, "_instance"):
            Member._instance = Member(*args, **kwargs)
        return Member._instance
def task(arg):
    obj = Member.instance()
    print(obj)
for i in range(5):
    t = threading.Thread(target=task, args=[i,])
    t.start()

이 코드의 실행 결과는 여러 객체가 인스턴스화되어 다음과 같이 작성하게 됩니다. 싱글톤이 작동하지 않습니다

물론 잠금을 통해 잠그고 제어하는 ​​것을 자연스럽게 생각하게 되므로 위 코드를 변경합니다. :

#! /usr/bin/env python3
# .-*- coding:utf-8 .-*-
import time
import threading
import random
class Member(object):
    _instance_lock = threading.Lock()
    def __init__(self):
        i = random.randint(1, 3)
        print(i)
        time.sleep(i)
    @classmethod
    def instance(cls, *args, **kwargs):
        with Member._instance_lock:
            if not hasattr(Member, "_instance"):
                Member._instance = Member(*args, **kwargs)
        return Member._instance
def task():
    obj = Member.instance()
    print(obj)

for i in range(5):
    threading.Thread(target=task,).start()

하지만 위 코드에는 또 다른 문제가 있습니다. 즉, 인스턴스화 후 인스턴스가 호출될 때마다 잠금이 요청되므로 좋지 않으므로 이 부분을 변경합니다.

@classmethod
    def instance(cls, *args, **kwargs):
        if not hasattr(Member, "_instance"):
            with Member._instance_lock:
                if not hasattr(Member, "_instance"):
                    Member._instance = Member(*args, **kwargs)
        return Member._instance

이것은 여러 스레드에서 사용할 수 있는 싱글톤을 구현하는 좋은 방법입니다.

위 내용은 이 기사의 전체 내용입니다. Python에 대한 더 흥미로운 내용을 보려면 주의하세요. PHP 중국어 웹사이트의

Python 비디오 튜토리얼

python 기사 튜토리얼 컬럼을 확인하세요! ! !

위 내용은 Python 싱글톤의 두 가지 구현 방법 소개(코드 포함)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 cnblogs.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제

관련 기사

더보기