2

次の例のように、Python クラスにシングルトンを使用しています

class GestionnaireUtilisateur(object):
    __singleton = None

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

    def __init__(self):
        self.compte = None

次のメソッドで self.__compte を変更できます

def connexion(self, compte):
    self.compte = compte

最初のオブジェクト GestionnaireUtilisateur() で、メソッド connexion('toto') を呼び出して self.compte を変更すると、結果は良好です。しかし、もう一度 GestionnaireUtilisateur() を呼び出すと、self.compte は None であり、connexion() によって渡される値ではありません。

オブジェクトが同じであるかどうかをテストします。私はこの結果を持っています

<securecloud.utilisateur.gstutilisateur.GestionnaireUtilisateur object at 0xb73aad4c>
toto
<securecloud.utilisateur.gstutilisateur.GestionnaireUtilisateur object at 0xb73aad4c>
None

誰かがアイデアを持っていますか?

4

4 に答える 4

2

__new__クラスのインスタンスを返すと、その関数__init__が呼び出されます。したがって、同じオブジェクトを再利用していますが、__init__毎回呼び出しています。

のような複雑なことはせずに行う方がよいでしょう__new__。このようにシングルトンを実装しようとする代わりに、ファクトリ関数を使用して 1 つのオブジェクトを作成して返します。

とにかく、このような強制的なシングルトンはしばしば悪い考えであり、テストはより複雑になり、それは本質的にグローバルな値であり、望ましくない結合につながります.

于 2012-06-28T16:09:32.977 に答える
0

シングルトン属性のオーバーライドを防ぐために、compteが存在する場合は__init__関数をチェックインできます。ただし、2番目のconnection()は最初のconnection()の値も変更します。

class GestionnaireUtilisateur(object):
    __singleton = None

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

    def connexion(self, compte):
        self.compte = compte

    def __init__(self):
        if not hasattr(self, "compte"):
            self.compte = None


s1 = GestionnaireUtilisateur()
print "'compte' before", s1.compte
s1.connexion('s1')
print "'compte' after", s1.compte

s2 = GestionnaireUtilisateur()
print "'compte' before", s2.compte
s2.connexion('s2')
print "'compte' after", s2.compte

print "s1 'compte' after", s1.compte

生成:

====================
instance s1
====================
'compte' before None
'compte' after s1
====================
instance s2
====================
'compte' before s1

'compte' after s2
s1 'compte' after s2
于 2012-06-28T16:14:05.370 に答える
0
class GestionnaireUtilisateur(object):
    __singleton = None

    def __new__(cls, *args, **kwargs):
        if not cls.__singleton:
            cls.__singleton = super(GestionnaireUtilisateur,
                cls).__new__(cls, *args, **kwargs)
            cls.__singleton._init()
        return cls.__singleton

    def __init__(self):
        print "Every time"

    def _init(self): # not __init__
        self.compte = None
        print "Once"
于 2012-06-28T16:14:44.520 に答える
0

@Ned が言ったように、シングルトンは一般的に正しい答えではありません。ファクトリ パターンを使用すると、柔軟性が大幅に向上します。これは、Python では基本的に簡単です。ただし、本当に状態を共有する必要がある場合は、Borg代わりにパターンを使用することを検討してください。

class Borg(object):
    __shared_state = {}

    def __init__(self):
        self.__dict__ = __shared_state
于 2012-06-28T16:22:48.920 に答える