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?
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()
...; -).
Aus der offiziellen Python-Dokumentation :
%Vor%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:
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.
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:
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.
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.
Versuchen Sie es
%Vor%Sie müssen der Klasse keinen Namen geben, wenn Sie nicht möchten
%Vor%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:
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.
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
Wenn Sie die Semantik eines Javascript-Objekts wünschen, können Sie die Namespaces-Bibliothek verwenden. Sie müssen nur pip install namespaces
zuerst.
vollständiger Disclaimer: Ich bin der Autor der namespaces
-Bibliothek.
Tags und Links python