0

Ich möchte nur in der Lage sein, die Instanzvariablen der Klasse foo zu entpacken, zum Beispiel:Auspacken Instanzvariablen durch Container machen iterable

x = foo("name", "999", "24", "0.222") 
a, b, c, d = *x 
a, b, c, d = [*x] 

Ich bin nicht sicher, wie auf der die richtige Methode ist so zu tun, wenn Implementieren meiner eigenen __iter__ Methode, jedoch ist die letztere, die mit gemischten "Erfolg" gearbeitet hat. Ich sage gemischt, weil dies mit dem vorgestellten Code zu tun scheint, um das ursprüngliche Instanzobjekt x so zu verändern, dass es nicht mehr gültig ist.

class foo: 
    def __init__(self, a, b, c, d): 
    self.a = a 
    self.b = b 
    self.c = c 
    self.d = d 

    def __iter__(self): 
    return iter([a, b, c, d]) 

Ich habe die unzähligen Beiträge auf dieser Website in Bezug auf __iter__, __next__, Generatoren usw., und auch ein Python-Buch und docs.python.org und scheinen nicht in der Lage zu Figur, was ich nicht verstehen. Ich habe gesammelt, dass __iter__ muss ein iterable (das kann nur self sein, aber ich bin mir nicht sicher, wie das funktioniert, was ich will). Ich habe auch verschiedene Möglichkeiten ausprobiert, __next__ zu implementieren und über vars(foo).items() zu iterieren, entweder durch Gießen in eine Liste oder als Wörterbuch, ohne Erfolg.

Ich glaube nicht, dass dies ein doppeltes Konto ist, dass die einzigen ähnlichen Fragen, die ich gesehen habe, ein einzelnes Listensequenz-Objektattribut darstellen oder einen Zahlenbereich anstelle von vier Nicht-Containervariablen verwenden.

+0

Was Sie eine Liste denken Rückkehr macht von '__iter__' Abspaltungen 'X'? Wenn das, was darüber iteriert wird, "a" usw. ändert, würde "x" sich ändern * aber * Sie implementieren den Iterator. Könnten Sie es einfach zu einer 'Sequenz' machen (d. H. Implementieren Sie' __getitem__' und '__len__' für https://docs.python.org/3/library/collections.abc.html)? – jonrsharpe

+0

Beim ersten Auspacken fehlt übrigens am Ende ein Komma. Könnten Sie auch "das ursprüngliche Instanzobjekt' x' "ändern? Wie das? –

+0

@jonrsharpe Ich nahm an, dass ich einen Iterator für die explizit definierte Liste zurückgab (d. H. Ich erlaube, dass die Instanzvariablen des Objekts wie eine normale Liste durchlaufen werden - und ähnlich entpackt werden). Ich kann versuchen, es zu einer Sequenz zu machen, sicher, es wird nur mehr lernen. Ich schätze diese Ressource definitiv und werde sie überprüfen. @ Jim Fasarakis-Hilliard, wie derzeit implementiert, wenn ich versuche zu tun, sagen: "a, b, c, d = * x," a, b, c und d werden die richtigen Werte halten, aber dann jeden Versuch, darauf zuzugreifen x - wie vor dem Entpacken - löst aus "TypeError: 'float' Objekt ist nicht untergruppierbar" – Todd

Antwort

1

Wenn Sie die Instanz-Variablen wollen, sollten Sie sie mit .self Zugang:

def __iter__(self): 
    return iter([self.a, self.b, self.c, self.d]) 

mit dieser Änderung

a, b, c, d = list(x) 

sehen Sie die Variablen erhalten.


Sie zum riskanten Verfahren gehen könnte vars(x) oder x.__dict__ verwenden, sortieren sie durch den Variablen-Namen (und deshalb ist es auch ein begrenztes ist, werden die Variablen in keiner Ordnung gespeichert) und Extrakt das zweite Element jedes Tupels. Aber ich würde sagen, der Iterator ist definitiv besser.

1

können Sie speichern die Argumente in einem Attribut (self.e unten) oder geben Sie sie auf Funktionsaufruf:

class foo: 
    def __init__(self, *args): 
    self.a, self.b, self.c, self.d = self.e = args 

    def __call__(self): 
    return self.e 

x = foo("name", "999", "24", "0.222") 
a, b, c, d = x.e 
# or 
a, b, c, d = x()