2016-08-21 7 views
2

Ich habe eine Python-Klasse A und seine Kind B. Ich mache ein Objekt der Klasse B übergeben einige Listen-Argumente, die in B angehängt sind und das Ergebnis in Klasse A. Ich würde gerne eines dieser Argumente ändern und sehen, dass sich die Änderung ohne weiteres widerspiegelt. Lassen Sie mich mit einem Beispiel erklären:Python verwenden Lazy-Zuweisung beim Übergeben von Listen an Methoden

class A(): 
    def __init__(self,data): 
     self.a=data 

class B(A): 
    def __init__(self,x,y): 
     self.x=x 
     self.y=y 
     A.__init__(self,self.x+self.y) 

    def change_x(self,x): 
     self.x = x 

Jetzt, wen ich laufe

test = B([1, 2], [3,4]) 
print(test.a) 

ich offensichtlich [1,2,3,4]. Wenn ich Teil der Liste wie folgt ändern:

test.change_x([3,4]) 
print(test.a) 

Ich würde [3,4,3,4] bekommen, anstatt natürlich erhalte ich [1,2,3,4]. Natürlich wird test.a nur während der Instanziierung ausgewertet.

Ich verstehe, warum das nicht der Fall ist, und ich lese über Generatoren, aber es gelingt mir nicht herauszufinden, wie dies zu implementieren ist. Ich möchte nicht mit einem iterablen Ergebnis enden, das ich nur einmal durchlaufen kann.

Konnte mir jemand helfen? Ein sauberer Weg, um das zu lösen?

+0

ich natürlich so etwas wie versuchen könnte: def change_x (self, x): Selbst .__ init __ (x, self.y) Aber ich bin mir nicht sicher, ob das ein guter Ansatz ist? – chrisvp

+0

Sie könnten 'a' eine Eigenschaft machen und sie in Klasse' B' überschreiben. – BlackBear

+0

Es gibt nicht wirklich eine Möglichkeit, das mit Ihrem aktuellen Design zu tun. In Ihrem Beispiel, warum ist "A" überhaupt eine Klasse (und warum ist es eine Superklasse von B)? Was Sie tun könnten, ist, B eine Methode zu geben, die das Äquivalent von "self.a.data" macht, aber das Ergebnis dynamisch berechnet. Wenn Sie "a" erstellen, erstellen Sie es mit einigen Daten und "a" weiß nicht, woher diese Daten stammen. Wenn Sie aktualisierte Daten erhalten möchten, ist es möglicherweise einfacher, dies in B zu tun und nicht "a" zu verwenden. – BrenBarn

Antwort

7

Gibt es einen Grund, die Klasse A überhaupt zu haben? Sie könnten eine Eigenschaft oder Methode a erstellen, die innerhalb der Klasse B den gewünschten Wert zurückgibt.

class B(): 
    def __init__(self, x, y): 
     self.x = x 
     self.y = y 

    def change_x(self, x): 
     self.x = x 

    @property 
    def a(self): 
     return self.x + self.y 


test = B([1, 2], [3, 4]) 
print(test.a) # [1, 2, 3, 4] 

test.change_x([3, 4]) 
print(test.a) # [3, 4, 3, 4] 

Kleine Anmerkung: Mit dieser Implementierung die change_x Methode nicht erforderlich sein sollte. Es ist im Allgemeinen mehr Pythonic, nur direkt auf Attribute zuzugreifen (z. B. test.x = x), als Getter und Setter zu verwenden.

+0

Hallo Karin, danke für deine Antwort.Wie ich gerade oben kommentiert habe: \t Hallo, ich habe versucht, ein minimal funktionierendes Design zu machen, das alle Bedeutung verloren hat. Ich implementiere Art eines Netzwerkprotokolls, Klasse A ist nur der Container für ein Paket. Klasse B hätte Kenntnis von Header, Cargo, Trailer Split. Klasse, z. B. WLAN, würde von B abgeleitet werden und den tatsächlichen Header und Trailer beschreiben. Klasse A würde eine Sendefunktion haben, Klasse B würde nur Daten verketten und vielleicht ein crc change_x berechnen, z. eher def mess_up_crc (selbst) (zu Testzwecken) – chrisvp

1

Sie müssen es "manuell" implementieren. Zum Beispiel, wie so:

class B(A): 
    def __init__(self,x,y): 
     self.x=x 
     self.y=y 
     self.spread_changes() 

    def change_x(self,x): 
     self.x = x 
     self.spread_changes() 

    def spread_changes(self): 
     A.__init__(self,self.x+self.y) 
0

Ich endete damit, alle Teile von self.a (in A) direkt zu speichern, indem ich sie aus ihren Klassen erschneide. Ich fügte eine Methode "B.update_crc (self)" hinzu, wie sie von Israel Unterman vorgeschlagen wurde, um bestimmte Teile von self.a im Falle einer Modifikation neu zu bewerten.

Danke, mein erster Ansatz wan't genau das Richtige :)

Verwandte Themen