Ich habe einen Code wie:
%Vor%es druckt:
%Vor%Wie kann ich Felder in einer ursprünglichen Reihenfolge erhalten: x, z, b, a? Ich habe ähnliches Verhalten in Django Models gesehen.
Wenn Sie, wie oben erwähnt, die Dinge einfach halten wollen, verwenden Sie einfach ein Attribut _ordering
, das die Reihenfolge manuell überwacht. Ansonsten ist hier ein Metaklassenansatz (wie der, den Django verwendet), der automatisch ein Ordnungsattribut erstellt.
Aufnahme der ursprünglichen Reihenfolge
Klassen verfolgen nicht die Reihenfolge der Attribute. Sie können jedoch verfolgen, in welcher Reihenfolge die Feldinstanzen erstellt wurden. Dafür müssen Sie eine eigene Klasse für Felder verwenden (nicht int). Die Klasse protokolliert, wie viele Instanzen bereits erstellt wurden, und jede Instanz merkt sich ihre Position. Hier ist, wie Sie es für Ihr Beispiel tun würden (Speichern von Ganzzahlen):
%Vor% Automatisches Erstellen eines ordered_items
-Attributs
Nun, da Ihre Felder eine Nummer haben, mit der sie sortiert werden können, muss Ihre Elternklasse diese irgendwie verwenden. Sie können dies auf verschiedene Arten tun, wenn ich mich richtig erinnere, verwendet Django Metaklassen, um dies zu tun, was für eine einfache Klasse ein bisschen wild ist.
%Vor%Verwenden Sie diese Metaklasse
Also, wie benutzt du das? Zuerst müssen Sie unsere neue MyOrderedField
-Klasse verwenden, wenn Sie Ihre Attribute definieren. Diese neue Klasse verfolgt die Reihenfolge, in der die Felder erstellt wurden:
Dann können Sie auf die bestellten Felder in unserem automatisch erstellten Attribut ordered_fields
:
Fühlen Sie sich frei, dies zu einem geordneten Diktat zu ändern oder geben Sie einfach die Namen oder was auch immer Sie benötigen zurück. Darüber hinaus können Sie eine leere Klasse mit dem __metaclass__
definieren und von dort erben.
Benutze das nicht!
Wie Sie sehen, ist dieser Ansatz ein wenig zu kompliziert und wahrscheinlich nicht für die meisten Aufgaben oder Python-Entwickler geeignet. Wenn Sie mit Python vertraut sind, werden Sie wahrscheinlich mehr Zeit und Mühe darauf verwenden, Ihre Metaklasse zu entwickeln, als wenn Sie die Reihenfolge manuell definiert hätten. Es ist fast immer der beste Ansatz, die eigene Bestellung manuell zu definieren. Django macht das automatisch, weil der komplizierte Code vor dem Endentwickler verborgen ist, und Django wird viel öfter verwendet, als es selbst geschrieben / verwaltet wird. Nur wenn Sie ein Framework für andere Entwickler entwickeln, können Metaklassen für Sie nützlich sein.
Ich war zu 80% mit dieser Antwort fertig, als Will seine veröffentlichte, aber ich entschied mich trotzdem zu posten, damit die Bemühungen nicht verschwendet würden (unsere Antworten beschreiben im Grunde das Gleiche).
So macht es Django. Ich habe mich dafür entschieden, die gleiche Nomenklatur, Methodik und Datenstruktur wie Django zu behalten, so dass diese Antwort auch für Leute nützlich sein kann, die versuchen zu verstehen, wie Feldnamen in Django sortiert sind.
%Vor%Nun wollen wir einige Beispielmodelle definieren:
%Vor%Und lassen Sie uns sie testen:
%Vor%Hoffe, das hilft, alles zu klären, was in Wills Antwort nicht klar war.
Djangos Modell- und Formularmetaklassen arbeiten mit den Feldbeschreibungen zusammen, um die ursprüngliche Reihenfolge beizubehalten. Es gibt keine Möglichkeit zu tun, was Sie fragen, ohne durch eine Menge von Reifen zu springen. Sehen Sie den Django-Quellcode, wenn Sie noch interessiert sind.
Sie können die Reihenfolge des Hinzufügens der Klassenvariablen nicht verfolgen. Diese Attribute (sowie Attribute für Objekte) werden intern als ein Wörterbuch gespeichert, das für schnelle Suchvorgänge optimiert ist und das Bestellen nicht unterstützt.
Sie können diese Tatsache sehen:
%Vor%Wenn Sie Ihre Attribute in einer bestimmten Reihenfolge haben möchten, können Sie einfach ein weiteres Feld hinzufügen, das diese Informationen enthält:
%Vor%Hinweis: In python 2.7 und 3.2 werden geordnete Wörterbücher als Teil der Standardbibliothek eingeführt.
Tags und Links python django introspection