@Jackaroo: Zuerst die direkten Fragen:
Klasse vs. Funktion: Klassen beschreiben "Dinge" und Funktionen und Methoden "Tätigkeiten". Das sollte sich in der Namensgebung wiederspiegeln und natürlich im Inhalt, also was der Quelltext anstellt.
`__`-Präfix: Wenn Du die Frage stellen musst, dann ist die Antwort wohl: Gar nicht. Dieser Präfix wurde eingeführt, um Namenskollisionen bei der Vererbung zu vermeiden und da insbesondere bei der Mehrfachvererbung, also wenn man Klassen entwirft die irgendwann einmal mit Klassen in einer Vererbungshierarchie landen, von denen man nichts weiss, und die auch von der eigenen Klasse nichts wissen. Solange man also keine Klasse entwirft, die als Mixin-Klasse verwendet werden soll, braucht man das nicht.
`self`: Klassen verbinden Daten und Funktionen die auf diesen Daten operieren zu einer Einheit. Die gemeinsamen Daten muss man an das Objekt binden, eben damit die anderen Methoden da heran kommen können. Alles was nur die Methode lokal benötigt, naja, ist eben lokal.
Zum Quelltext: Zur Namensgebung solltest du mal einen Blick in den Style Guide (a.k.a. PEP8) werfen. Für Konstanten GROSSBUCHSTABEN_UND_UNTERSTRICHE, Klassen in MixedCase und alles andere in klein_mit_unterstrichen.
Was dann auffällt ist, dass das Eingabeformat anscheinend CSV mit Semikolon als Trenner ist und das Ausgabeformat XML und Du das alles *selbst* erledigst. In der Standardbibliothek gibt es das `csv`-Modul und den `xml.etree.ElementTree.TreeBuilder`.
Die Klasse `ExportFile` ist mir vom Sinn her nicht so ganz klar. Wenn eine Klasse in der der `__init__()` alles erledigt, dann ist das oft ein Zeichen, dass man eigentlich mit einer Funktion auskommen würde. In diesem Fall zum Beispiel eine, die die erste Zeile und den Rest der Zeilen als Tupel zurück gibt.
Allerdings würde ich die Datei gar nicht komplett einlesen, sondern eher "lazy" verarbeiten. Wenn die erste Zeile die Spaltennamen enthält, ist ein `csv.DictReader` das Mittel der Wahl.
`Asset.tagFields()` ist sehr verwirrend. Wenn ich das richtig sehe hast Du versucht eine ganz einfach ``for``-Schleife möglichst kompliziert und undurchsichtig zu schreiben.

Letztendlich ist das aber einfach nur: ``self.tagged_fields = zip(tags, self.fields)``. Wobei hier in einer Methode plötzlich ein neues Attribut auf dem Objekt erzeugt wird. Das ist IMHO schlechter Stil. Vom Lesen der `__init__()` sollte klar werden, welche Attribute ein Objekt besitzt, und nach Abarbeitung der `__init__()` sollte es in der Regel in einem benutzbaren Zustand sein. Wenn der Inhalt der Klasse letztendlich nur aus einem `split()` der Eingabezeile und einem `zip()` besteht, und das `split()` eigentlich schon vom `csv`-Reader übernommen wird, erscheint auch diese Klasse mit einer einfachen Funktion oder sogar komplett "inline" umgesetzt werden zu können.
Der Datentyp sollte in Namen möglichst nicht auftauchen. Wenn man zum Beispiel statt einer Liste irgendwann einmal einen anderen Typ verwendet, muss man entweder alle betroffenen Namen anpassen, oder man hat verwirrenden Quelltext.
`XMLOutput` beschreibt die Klasse nicht gut. `XMLWriter` trifft es genauer was die Klasse macht.
`writeFields()` ist für meinen Geschmack zu kompliziert. Ich hätte das umsetzen in eine verschachtelte Struktur und das Entfernen von leeren Unterstrukturen in zwei Schritte aufgeteilt und wohl rekursiv statt iterativ gelöst.
Zum Rest von der `XMLOutput` sage ich jetzt mal nichts, weil ich mich nicht durch die Logik arbeiten möchte, die man ohne konkrete Beispiele wahrscheinlich nur schwer versteht.
Ich bin kein grosser Fan von ``continue`` weil das eine Sprunganweisung ist, die mitten aus einem Block wieder an den Anfang springt und damit das ganze nicht so schön an der Einrückung ersichtlich ist. Ich hätte für das Hauptprogramm eher eine Funktion geschrieben, welche die Dateinamen filtert und dann über das Ergebnis die Schleife geschrieben. Oder den ``else``-Zweig weg gelassen und dafür den Rest des Schleifenköpers eine Ebene weiter eingerückt.
Zum Schluss ist dann wieder so eine komische ``while``-Schleife die man viel einfacher als ``for``-Schleife ausdrücken könnte.
Alles ab dem ``# MAIN``-Kommentar sollte in einer Funktion verschwinden. Auf Modulebene sollten nur Importe und Konstanten-, Funktions-, und Klassendefinitionen stehen. Und die Hauptfunktion kann man mit folgendem Idiom vor dem ausführen schützen, wenn man das Modul nur importiert statt es als Programm auszuführen:
Dann kann man das Modul importieren und einzelne Funktionen und Klassen ausprobieren, oder wiederverwenden, oder Werkzeuge benutzen, die aus dem Quelltext API-Dokumentation extrahieren.