Python Singleton:相同的对象但值不同

时间:2012-06-28 16:04:03

标签: python singleton initialization

我正在使用单例作为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

我可以使用以下方法修改自我.__ compti

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 个答案:

答案 0 :(得分:2)

__new__返回类的实例时,会调用__init__函数。所以你重复使用相同的对象,但每次都在它上面调用__init__

最好不要使用__new__之类的复杂内容。不要试图像这样实现单例,只需使用工厂函数来创建和返回一个对象。

无论如何,像这样的强迫单身人士往往是个坏主意,测试变得更加复杂,而且它本质上是一个全局价值,导致不必要的耦合。

答案 1 :(得分:0)

如果存在compte,您可以检入__init__函数,以防止覆盖singleton属性。但第二个连接()也会改变第一个连接的值。

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

答案 2 :(得分: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"

答案 3 :(得分:0)

正如@Ned所说,单身人士通常不是正确答案。通过使用工厂模式可以获得更大的灵活性,这在Python中基本上是微不足道的。但是,如果您确实需要共享状态,请考虑改为使用Borg模式。

class Borg(object):
    __shared_state = {}

    def __init__(self):
        self.__dict__ = __shared_state