0

以下のコードでシングルトンデザインパターンを適用しようとしています

class SMSMgr( object ):
    _instance = None
    def __init__(self):
            self._allsp = []
    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = super(SMSMgr, cls).__new__(
                                cls, *args, **kwargs)
        return cls._instance

    def loadsettings(self):
        get_all_sp = ServiceProvider.objects.filter(status = False)
        for obj in get_all_sp:
            cla = obj.class_Name
            a=globals()[str(obj.class_Name)](obj.userName,obj.password,obj.sendingurl)
            self._allsp.append(a)
            #print self._allsp
    def send(self):
        print "+++++++++++++++++++== Global send "


if __name__ == "__main__":

    b = SMSMgr()
    b.loadsettings()
    print b._allsp
    print "b end -------------------"
    c = SMSMgr()
    c.loadsettings()
    print c._allsp
    print "c end -------------------"

シングルトンによると、bオブジェクトはcオブジェクトと同じである必要があります。しかし、上記のコードを実行しているときは、さまざまなオブジェクトを取得しています。シングルトンとしてこれを実行する方法を教えbc ください。

4

2 に答える 2

2

あなたのシングルトンパターンは私にはうまくいくはずです。が__init__両方とも呼び出されているため、新しいインスタンスを作成するself._allspとリセットされて、新しいインスタンスがあるように見える可能性はありますか?

次のように入力して、それらが実際に同じインスタンスであるかどうかを確認できます。

print b is c

スクリプトの最後に。True(それらが同じ場合は印刷されます)

私が考えることができる最も簡単な修正は_allsp、クラス属性を作成してから削除することです__init__。例えば

class SMSMgr( object ):
    _instance = None
    _allsp = []
    def __init__(self):
        pass

上記で説明したように、期待どおりにシングルトンを作成するテスト済みのコードを次に示します。

class SMSMgr( object ):
    _instance = None
    _allsp = []
    def __init__(self):
        pass

    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = super(SMSMgr, cls).__new__(
                                cls, *args, **kwargs)
        return cls._instance

    def foo(self,arg):
        self._allsp.append(arg)

    def bar(self):
        print self._allsp

a = SMSMgr()
a.foo(1)
b = SMSMgr()
b.foo(2)
a.bar()
b.bar()
print a is b
于 2013-02-05T14:39:10.627 に答える
0

ここでの問題は、あなたの番兵がいないことだと確信しています__init__。そのため、各インスタンス化は同じオブジェクトを返しますが、毎回__init__再実行されます。あなたはこのようなことを試すことができます:

def __init__(self):
    if not hasattr(self, '_allsp'):
        self._allsp = []

より堅牢なソリューションの場合は、おそらく次のようなものが必要です。

def __init__(self):
    if not hasattr(self.__class__, 'inited'):
        self._allsp = []
        self.__class__.inited = True

ある種のロックでinit機能をラップしない限り、これはスレッドセーフではないことに注意してください。

@mgilsonが彼の答えで理解しているように、Pythonでシングルトンを作成しようとしている場合は、インスタンス属性の代わりにクラス属性を使用し、クラスを完全に分離することが理にかなっているのかどうかを確認する必要があります。最初に、またはそれを他の非シングルトンクラスに折りたたむ。シンゲトンとPythonが同じ段落で取り上げられるときに頻繁に言及されるパターン、ボーグパターンもあります。

于 2013-02-05T14:41:29.163 に答える