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__. 与其尝试像这样实现单例,只需使用工厂函数来创建和返回一个对象。

无论如何,像这样的强制单例通常是一个坏主意,测试变得更加复杂,而且它本质上是一个全局值,这会导致不必要的耦合。

于 2012-06-28T16:09:32.977 回答
0

如果存在 compte,您可以检查 __init__ 函数,以防止覆盖单例属性。但是第二个 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 回答