Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Die Attribute gibt es in nicht in der Reihenfolge. Fraglich ist auch in welcher Reihenfolge Attribute gelistet werden sollen, die nicht in ``__init__`` erstellt werden.
Wenn dir diese Reihenfolge wirklich so wichtig ist, duerfte das ``ast`` Modul eine Moeglichkeit sein.
Man könnte einen Wrapper mittels `.__setattr__()` schreiben, der das Setzen der Attribute in einem `OrderedDict` oder einer `list` (wenn einen nur die Namen interessieren) protokolliert und anschließend `object.__setattr__()` aufruft. Das hieße, man schreibt eine entsprechende Basisklasse mit einem `._attr_names`-Attribut oder sowas und greift zum Protokollieren darauf zu. Übrigens: Eine überschriebene `.__delattr__()`-Methode als Gegenstück sollte man dann sinnvollerweise auch einbauen.
Die Alternative wäre natürlich, für die Basisklasse direkt `.__dict__` mit einem `OrderedDict` zu überschreiben. Allerdings weiß ich nicht, ob das unangenehme Seiteneffekte hätte.
Auf jeden Fall kommt man nicht drumherum, das Setzen der Attribute irgendwie abzufangen. Denn wenn die Attribute einmal gesetzt wurden und dabei in einem herkömmlichen `dict` gelandet sind, dann kann man die Original-Reihenfolge nicht mehr nachvollziehen. Mit anderen Worten: Ein nachträgliches Modifizieren einer Klasseninstanz oder irgendwelche Kniffe via Introspektion würden nicht zum gewünschten Ziel führen.
@pyseidon: willst Du XML nur als Serialisierungsformat wie Pickle oder JSON verwenden? Dann ist die Reihenfolge ja egal, weil nach dem Einlesen alles wieder in unsortierten Wörterbüchern landet. Oder hast Du eine XML-Definition, die die Reihenfolge vorschreibt. Dann mußt Du die XML-Struktur explizit definieren, weil Tag-Namen nicht den Python-Namensgebung entsprechen, weil manche Attribute vielleicht XML-Attribute und andere Subelemente werden, weil Du Hilfsattribute hast, die nicht mitgespeichert werden sollen/dürfen, weil es Datentypvorgaben gibt, die Du prüfen mußt. Listen kann man ja auf verschiedene Arten in XML abbilden, und müßte dann verschiedene Listen-Klassen in Python verwenden, womit dann Deine Programmkomplexität enorm steigt, nur um das richtige XML zu erzeugen.
Ich habe mal einen XSD-Converter geschrieben, der die Definitionen in Wrapperklassen umschreibt, und bin daran gescheitert, dass XSD einfach viel zu kompliziert ist. Dann habe ich die Object-XML-Wrapperklassen von Hand geschrieben, um daraus XSD- bzw. XML-Dateien schreiben zu können, ähnlich SQLAlchemy. Das Ergebnis war nicht befriedigend, da der Strukturoverhead für meinen Geschmack zu groß und der Gestaltungsfreiraum zu klein war. Will sagen, maschinell erzeugtes XML sieht wie maschinell erzeugtes XML aus, und ist für den Menschen nur schwer lesbar.
Inzwischen schreibe ich meine Serialisierungs- und Deserialisierungsmethoden liebevoll von Hand und bin zufrieden damit.
@cofi: Es kommen alle relevanten Attribute in `__init__` vor.
@snafu: Sowas kam mir auch in den Sinn. Muss ich mal schauen ob sich der Aufwand lohnt.
@pillmuncher: Hmm, den Visitor Pattern könnte ich mir auch noch anschauen.
@Sirius3: Die Reihenfolge ist relevant, soll ja valides XML herauskommen. Die Namensgebung ist ehr nicht das Problem. Da kann ich einfach ein `upper()` benutzen und schon habe ich zu dem Attribut (lower_case_with_underscores) den entsprechenden XML-Element-Namen (UPPER_CASE_WITH_UNDERSCORES). Bei Klassennamen müsste ich das CamelCase umwandeln, sollte aber kein Problem sein.
Ja, bei über 100 Klassen macht das Spaß die XML-Representationen selber zu schreiben. Wollte mir da mit einem generischen Ansatz die Arbeit etwas vereinfachen.
@pyseidon: Du hast also eine Vorgabe, wie das XML aussehen soll. Dann mußt Du also alle Deine Klassen den Vorgaben entsprechend schreiben, darfst keine zusätzlichen (internen) Attribute, hinzufügen, darfst nicht mit Properties und anderem nicht-__dict__ basiertem Zeugs arbeiten. Kurz, Du bist in der Art, wie Du Deine Python-Klassen programmierst sehr stark eingeschränkt. Und das Problem der Typisierung ist auch nicht gelöst. Das findet vielleicht ein Java-Programmierer toll, aber ein Pythonprogrammierer würde den Job wechseln. Sauberer ist es eine generische Abstraktionsschicht hinzuzufügen, oder gleich alles händisch zu machen. Der Aufwand ist vielleicht etwas größer, die gewonnene Freiheit wiegt das allemal wieder auf. Und die Tagnamen sind wirklich GROSS_BUCHSTABEN_MIT_UNDERSTRICH. Dann zählt das Argument, dass das irgendein Mensch lesen oder schreiben will, wirklich nicht mehr.
Oder bist Du frei in der Art wie das XML aussehen soll und wie es validiert wird. Sowohl XSD als auch Relax-NG erlauben es, dass die Reihenfolge der Tags beliebig sein kann. Und die übliche XML-Namenskonvention ist lowercase-with-hyphen.
@Sirius3: Ich muss mich an ein standardisiertes Austauschformat halten. Wie ich da meine Klassen schreiben ist (fast) vollkommen egal. Es muss eben das korrekte XML herauskommen. Das Format ist durchaus zum menschlichen Lesen gedacht, sonst hätte man das Ganze Format anders aufziehen können.
Und die übliche XML-Namenskonvention ist lowercase-with-hyphen.
Naja, mit dem üblich ist das so eine Sache. Ist mir ehrlich gesagt ganz selten untergekommen.