2012-06-28 27 views
2

我使用一個單一蟒類如以下示例的Python的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 __init__(self): 
     self.compte = None 

我可以modifie自.__孔特以下方法

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 

有人有一個idee?

+0

改爲使用模塊。 http://stackoverflow.com/q/31875/10077 –

回答

2

__new__返回該類的一個實例時,將對其調用__init__函數。因此,您正在重複使用同一個對象,但每次都調用__init__

沒有像__new__這樣的複雜事情會更好。不要試圖像這樣實現一個單例,只需使用工廠函數來創建並返回一個對象。

無論如何,這樣的強制單身通常是一個壞主意,測試變得更加複雜,而且它本質上是一個全局值,它會導致不必要的耦合。

+0

好的,我明白我的錯誤與__new__。謝謝 – Liberitus

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 
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" 
0

正如@Ned說,單身人士一般不是正確答案。你可以通過使用工廠模式獲得更多的靈活性,這在Python中基本上是微不足道的。但是,如果您確實需要共享狀態,請考慮使用Borg模式。

class Borg(object): 
    __shared_state = {} 

    def __init__(self): 
     self.__dict__ = __shared_state 
相關問題