2010-11-08 6 views
1

J'ai une question python qui, j'en suis sûr, est assez simple - n'hésitez pas à me désabuser de toute mauvaise pratique pendant que vous y êtes. J'ai le code suivant:python 2.7 __init__ comportement sur soi

class User(dict,BaseDBI): 
    def __init__(self,uid=None,username=None): 
     self['uid']=str(uuid())  
     if uid == None and username is not None:    
      uid_struct = self.Get('data/username.kch',username)   
      if uid_struct is not None: 
       self = self.Get('data/user.kch',uid_struct['uid']) 

Comme vous pouvez le dire, cet utilisateur est simplement un objet dict étendu. Il accède également à quelques méthodes Get et Set simples sur un couple de fichiers Kyoto Cabinet db. Je mis dans certaines déclarations d'impression de tracer à travers ce qui se passe et tout est bien réglé, mais lorsque je crée un objet utilisateur (par exemple):

user = User(username='someusername') 

puis l'utilisateur d'impression je n'ai qu'un nouvel objet dict qui a le nouveau uid généré par la première ligne sous __init__

Merci pour toute sagesse!

+0

Quel est le problème? –

+0

pourquoi hérite-t-il de dict de toute façon? Êtes-vous sûr de ne pas vouloir appeler les classes de base '__init__'? Bien sûr, vous obtenez un «dict», ce devrait être un objet qui ressemble à un dict? –

Répondre

2

Les variables python sont des références. Lorsque vous affectez à self, vous remplacez cette référence sans modifier l'objet renvoyé par __init__. La méthode la plus simple consiste à utiliser la méthode dict.update pour copier toutes les paires clé/valeur dans self. Cela devrait 'fonctionner' puisque vous héritez déjà de dict.

L'héritage n'est approprié que pour une relation telle que A is a B. Vous indiquez qu'un Utilisateur est un dict, c'est bien, mais je doute qu'un Utilisateur soit un BaseDBI. Il est plus probable que vous vouliez qu'un utilisateur ait une base de données, auquel cas la composition est plus appropriée. Cela semble probablement difficile, mais vous empêchera de faire des systèmes bizarres et obscènes.

+0

Merci beaucoup pour votre aide. En outre, merci pour la suggestion de composition - il est préférable d'obtenir cette rétroaction maintenant que plus tard. – swasheck

0

Vous devez appeler les constructeurs hérités. Quelque chose comme:

def __init__(self,uid=None,username=None): 
    dict.__init__(self) 
    BaseDBI.__init__(self) 

assignant également à self va simplement remplacer la valeur de la variable locale self. Cela n'aura aucun effet sur l'objet.

0

Si vous avez besoin de retourner une instance déjà existante ou votre classe, vous devez définir une méthode __new__

Au moment où __init__ est appelé, une nouvelle instance a déjà été créé

+0

Merci. Ce sera toujours une nouvelle instance, pour autant que je sache. – swasheck

+0

@swasheck, ahh, on dirait que tu n'as pas vraiment l'intention de te rebeller –

Questions connexes