Strukturobjekte in Python

8

Ich wollte ein wegwerfbares "struct" -Objekt erstellen, um verschiedene Status-Flags zu behalten. Mein erster Ansatz war dies (Javascript-Stil)

%Vor%

Definitiv nicht das, was ich erwartet habe, denn das funktioniert:

%Vor%

Ich vermute, das liegt daran, dass object () kein __dict__ hat. Ich möchte kein Wörterbuch verwenden und unter der Annahme, dass ich das Anon-Objekt nicht erstellen möchte, gibt es eine andere Lösung?

    
Stefano Borini 10.12.2009, 04:55
quelle

8 Antworten

21

Die kürzeste Möglichkeit, "ein generisches Objekt, dem Sie Attribute zuweisen / abrufen können" zu machen, ist wahrscheinlich:

%Vor%

Wie die meisten anderen Antworten zeigen, gibt es viele andere Möglichkeiten, aber es ist schwer, diese für Prägnanz zu schlagen ( lambda:0 ist genau die gleiche Anzahl von Zeichen wie object() ...; -).

    
Alex Martelli 10.12.2009, 05:31
quelle
15

Aus der offiziellen Python-Dokumentation :

  

9.7. Wahrscheinlichkeiten und Enden

     

Manchmal ist es nützlich, Daten zu haben   Typ ähnlich dem Pascal "record" oder   C "struct", bündelt ein paar   benannte Datenelemente. Eine leere Klasse   Definition wird gut tun:

%Vor%

Das scheint natürlich und einfach: Pythonic. Denk an das Zen! "Einfach ist besser als komplex" (Nummer 3) und "Wenn die Umsetzung ist leicht zu erklären, kann es eine gute Idee sein "(Nummer 11)

Zusätzlich ist ein struct nichts anderes als ein class mit öffentlichen Mitgliedern (d. h. struct{}; und class{public:}; sind genau dasselbe (in, sagen wir, C ++)). Sollten Sie das nicht in Betracht ziehen und künstliche Konstrukte in Ihrem Python-Programm vermeiden? Python soll lesbar, wartbar und leicht zu verstehen sein.

    
Escualo 10.12.2009 05:21
quelle
9

Ich hatte einmal dieselbe Frage. Ich fragte es in einer Mailing-Liste, und Alex Martelli wies darauf hin, dass object die Basis aller Vererbung in Python ist; Wenn object() eine Klasseninstanz mit einem eigenen Wörterbuch erstellt, müsste jedes Objekt in Python ein eigenes Wörterbuch haben, und das würde Speicher verschwenden. Zum Beispiel sind True und False Objekte; Offensichtlich brauchen sie keine eigenen Wörterbücher!

Ich würde mich freuen, wenn es eine Art eingebautes Python-Feature gäbe, bei dem ich einfach sagen könnte:

%Vor%

Aber es ist trivial, struct() zu schreiben:

%Vor%

Oder Sie könnten eine etwas komplexere tun:

%Vor%

Je komplexer Sie dies tun können:

%Vor%

Aber es ist so trivial, struct() zu schreiben, dass ich denke, dass es sich nicht lohnte, die Sprache hinzuzufügen. Vielleicht sollten wir versuchen, eine Standardfunktion zu collections module oder etwas hinzuzufügen.

    
steveha 10.12.2009 05:26
quelle
4

Ich persönlich denke, dass die sauberste Lösung das ist, was Sie bereits vermutet haben:

%Vor%

Ich weiß, dass du gesagt hast, dass du kein __dict__ willst, aber das verwirrt mich, da ich keinen Grund sehe, mich darum zu kümmern. Sie müssen nicht auf __dict__ verweisen, das ist ein internes Python-Implementierungsdetail. Wie auch immer, jede Instanz in Python, die das dynamische Hinzufügen von Attributen erlaubt, hat __dict__ , weil Python so dynamische Attribute ausführt. Selbst wenn die Instanz auf eine wirklich clevere Art erstellt wird, wird sie __dict__ haben.

Wenn Sie dies noch nicht getan haben, empfehle ich PEP 20 und PEP 8 (Nr Reputation, also nur ein Link für mich.) Nicht, dass die PEPs sich direkt auf deine Frage beziehen, aber ich denke, dass es nützlich ist, Python auf Pythonic Weise zu benutzen.

    
Mark Evans 10.12.2009 12:04
quelle
3

Versuchen Sie es

%Vor%

Sie müssen der Klasse keinen Namen geben, wenn Sie nicht möchten

%Vor%     
John La Rooy 10.12.2009 05:15
quelle
2

Das Geheimnis ist hier der Unterschied zwischen Objekten und Klasseninstanzen .

In Python ist alles ein Objekt. Klassen sind Objekte, Ganzzahlen sind Objekte, Typen sind Objekte und Klasseninstanzen sind Objekte. Wenn Sie object() sagen, erhalten Sie ein einfaches Basisobjekt. Es ist nichts. Völlig nutzlos. Untergeordnete Ebene als alles andere, auf das Sie in Python verweisen können.

Sie haben wahrscheinlich gedacht, dass das Aufrufen von object() Ihnen eine Klasseninstanz gibt. Das ist verständlich, weil Sie wahrscheinlich gedacht haben, dass object eine Klasse ist. Es ist nicht. Auch wenn Sie das vielleicht denken, denn es ist die Basisklasse, die für neue Klassendefinitionen verwendet wird:

%Vor%

object ist in der Tat ein Typ (ähnlich wie str und int Typen sind). Wenn Sie object() aufrufen, konstruieren Sie keine Klasseninstanz, indem Sie einen speziellen Objekttyp instanziieren. Aber in object ist es besonders, wie vollständig blah ist.

Nur Klasseninstanzen haben die besondere Fähigkeit, Dinge mit Punktnotation anzuheften. Das ist keine allgemeine Eigenschaft aller Objekte. Stell dir vor, wenn das der Fall wäre! Du könntest verrückte Sachen wie das Hinzufügen von Eigenschaften zu Strings machen:

%Vor%

Offensichtlich können Sie das nicht tun.

    
jpsimons 10.12.2009 05:25
quelle
2

Natürlich gibt es immer eine namedtuple . Es ist billig und schnell, aber unveränderlich - Sie müssen Ihre Attributnamen und -werte im Voraus kennen, und Sie können ihre Werte später nicht ändern. Aber zumindest hat es die Struktur / Objekt-Attribute getters. Und es wird mit Python 2 und 3 arbeiten

%Vor%     
hobs 13.01.2014 19:53
quelle
1

Wenn Sie die Semantik eines Javascript-Objekts wünschen, können Sie die Namespaces-Bibliothek verwenden. Sie müssen nur pip install namespaces zuerst.

%Vor%

vollständiger Disclaimer: Ich bin der Autor der namespaces -Bibliothek.

    
Pedro Cattori 13.10.2016 16:32
quelle

Tags und Links