2010-12-15 9 views
2

ich habe:Python. Definieren Sie „-Attribut anfängliche Methode“

class C: 
    aaa=2 


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

Wie i-Klasse definieren können C so, wenn ich dynamisch Attribut Instanz festgelegt es dieses Attribut Instanz der Klasse B machen. Und der Attributname der Klasse B muss das Attribut name haben gleiche Zeichenfolge des Namens dieses neuen Attributs in der Klasse C und das Attribut value der B Instanz muss einen Wert haben, der im neuen Attribut in der Instanz der Klasse C gesetzt ist.

haben mir dieses Ergebnis zu geben:

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

Ich möchte Sie ermutigen, an der Klarheit Ihrer Frage zu arbeiten. – NPE

+0

Sorry, ich wusste gar nicht was Weltklarheit bedeutet. :) Aber ich denke du kannst Klarheit aus einem Code bekommen ... :) Aber auf jeden Fall Panzer für mich, um Englisch zu lernen) ... – Pol

+0

Warum würdest du das wollen? –

Antwort

5

Nur __setattr__ intelligent außer Kraft setzen. Wenn Sie es nur für ein bestimmtes Attribut tun wollen, dann setzt in einem speziellen Fall für die Attributnamen, die Sie suchen mögen:

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

Wenn Sie es für jedes Attribut wollen, vergessen Sie einfach die if und es wird es für alles tun:

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

Ich denke, das ist die richtige Idee, aber die OP will * alle * dynamisch Attribute der 'Klasse C' zu Instanzen der' Klasse B', nicht nur einige mit einem speziellen Namen. - also kein 'if name == 'makeMeB':' erforderlich. – martineau

+0

Ja, das war nicht klar aus der Frage, also ging ich mit der etwas spezifischeren Version, die einfacher zurück skalieren wäre. Ich werde auch den anderen bearbeiten. –

+1

Aber benutze '__dict__' nicht direkt, benutze stattdessen 'super (C, self) .__ setattr__' (und dann müsstest du auch neue Stilklassen über Unterklassenobjekte verwenden, was ich sowieso empfehlen würde). Andernfalls kann es passieren, dass "__setattr__" Anpassungen von Superklassen, die man verwenden kann, unterbrochen werden. – nils

1

Dies ist eine schreckliche Sache, zu tun, weil es ändert sich, was bedeuten Attribute!

Warum nicht nur bei der __dict__ von c:

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

Ah aber du kannst :) Sieh meine Antwort! –

+0

@Daniel: Oh, ich verstehe! Ich habe die Frage nicht richtig analysiert. Was für eine böse Sache zu tun: p – katrielalex

Verwandte Themen