2010-12-15 48 views
2

je:Python. Définir attribut « méthode initiale »

class C: 
    aaa=2 


class B: 
    def __init__ (self,name): 
     self.name 
     self.value 

Comment définir la classe C donc quand je définir dynamiquement attribut exemple, il fait cette instance d'attribut de classe B. Et le nom d'attribut de la classe B doit avoir l'attribut name chaîne égale de nom de ce nouvel attribut dans la classe C et l'attribut value de B instance doivent avoir la valeur que définir dans nouvel attribut dans l'instance de la classe C.

doivent me donner ce résultat:

>> c=C() 
>> c.whatever= 'strinstrinsstring' 
>> isinstance(c.whatever,B) 
True 
>> c.whatever.value 
'strinstrinsstring' 
>>c.whatever.name 
'whatever' 
+4

Je voudrais vous encourager à travailler sur la clarté de votre question. – NPE

+0

Désolé, je ne savais même pas ce que signifie la clarté du monde. :) Mais je pense que vous pouvez obtenir la clarté d'un code ... :) Mais de toute façon les chars pour me pousser à apprendre l'anglais) ... – Pol

+0

Pourquoi voudriez-vous cela? –

Répondre

5

Juste intelligemment outrepasser __setattr__. Si vous voulez le faire que pour un attribut spécifique, puis mis dans un cas particulier pour le nom de l'attribut que vous souhaitez rechercher:

>>> class B: 
    def __init__(self, name, value): 
     self.name = name 
     self.value = value 


>>> class C: 
    def __setattr__(self, name, value): 
     if name == 'makeMeB': 
      newb = B(name, value) 
      self.__dict__[name] = newb 
     else: 
      self.__dict__[name] = value 

>>> c = C() 
>>> c.makeMeB = 'foo' 
>>> isinstance(c.makeMeB, B) 
True 
>>> c.makeMeB.name 
'makeMeB' 
>>> c.makeMeB.value 
'foo' 
>>> c.blah = 'foo' 
>>> isinstance(c.blah, B) 
False 

Si vous le voulez pour chaque attribut, juste oublier le if et il le fera pour tout:

>>> class B: 
    def __init__(self, name, value): 
     self.name = name 
     self.value = value 


>>> class C: 
    def __setattr__(self, name, value): 
     attr_as_b = B(name, value) 
     self.__dict__[name] = attr_as_b 

>>> c = C() 
>>> c.makeMeB = 'foo' 
>>> isinstance(c.makeMeB, B) 
True 
>>> c.makeMeB.name 
'makeMeB' 
>>> c.makeMeB.value 
'foo' 
>>> c.amIalsoB = 'well?' 
>>> isinstance(c.amIalsoB, B) 
True 
>>> c.amIalsoB.name 
'amIalsoB' 
>>> c.amIalsoB.value 
'well?' 
+0

Je pense que c'est la bonne idée, mais l'OP veut * tous * dynamiquement définir les attributs de la classe C à être des instances de la classe B, pas seulement certains avec un nom spécial. - donc non 'if name == 'makeMeB':' obligatoire. – martineau

+0

Ouais ce n'était pas clair à cause de la question, alors je suis allé avec la version légèrement plus spécifique qui serait plus facile à réduire. Je vais aussi éditer l'autre. –

+1

Mais n'utilisez pas '__dict__' directement, utilisez' super (C, self) .__ setattr__' à la place (et vous devrez alors utiliser des classes de style nouveau via l'objet de sous-classe, ce que je recommanderais quand même). Dans le cas contraire, cela peut casser les personnalisations '__setattr__' des superclasses que l'on peut utiliser. – nils

1

C'est une chose horrible à faire, parce que ça change ce que signifie les attributs!

Pourquoi ne pas regarder juste au __dict__ de c:

>>> class C(object): 
...  pass 
... 
>>> c = C() 
>>> c.spam = 'ham' 
>>> c.__dict__ 
{'spam': 'ham'} 
+0

Ah mais vous pouvez :) Voir ma réponse! –

+0

@Daniel: oh, je vois! Je n'ai pas analysé correctement la question. Quelle mauvaise chose à faire: p – katrielalex