ホームページ > バックエンド開発 > Python チュートリアル > Pythonシングルトンの2つの実装方法を紹介(コード付き)

Pythonシングルトンの2つの実装方法を紹介(コード付き)

不言
リリース: 2018-10-12 15:37:00
転載
2073 人が閲覧しました

この記事では、Python シングルトンの 2 つの実装方法 (コード付き) を紹介します。一定の参考価値があります。困っている友人は参考にしてください。お役に立てれば幸いです。

この 2 日間、以前に書いたコードを眺めていたので、使用したものを整理しました。シングルトン モードは日常のコード作業でよく使用されます。

ここでは、これまでさまざまな方法で実装されてきたシングルトン メソッドの概要を示します。

Decorator メソッド

このメソッドは仕事でもよく使用されます。コードは次のように実装されています

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 中国語 Web サイトの記事チュートリアル

列の

Python ビデオ チュートリアル および python に注目してください。 ! !

以上がPythonシングルトンの2つの実装方法を紹介(コード付き)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:cnblogs.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート