@andi_wand: Das wäre etwas schöner zu lesen, wenn Du Dich an den
PEP 8 -- Style Guide for Python Code halten würdest und nicht alles so „aneinander kleben“ würde.
Falls die Zeichenketten mit den Kommentareb DocStrings werden sollten, dann stehen sie an der falschen Stelle. Die gehören *hinter* die Definitionszeilen. Nur dann werden sie von Python als DocStrings erkannt und entsprechend verarbeitet.
Um Bedingungen muss man keine Klammern setzen.
`__del__()` ist eine ganz böse Falle! Das ist *kein* deterministischer Destruktor. Vergiss am besten, dass es diese Methode überhaupt gibt. Wenn man nicht genau weiss wie das intern funktioniert, sollte man die Finger davon lassen. Selbst wenn `__del__()` das tun würde, was Du vermutest, wäre es unsinnig die Datei solange offen zu lassen wie das Objekt besteht.
`maze_Rows` auf Klassenebene hat da sicher nichts zu suchen.
Was Deine `readIn()`-Methode da macht, habe ich nicht verstanden!? Das sieht mir auch zu umständlich aus um es näher anzuschauen, denn alles was Du da machst ist sicher so nicht nötig. Das sieht auch nicht nach Python aus, sondern nach einer anderen Sprache.
Du führst ausserhalb der `__init__()` neue Attribute auf dem Objekt ein — das sollte man nicht machen. Ich denke auch nicht, dass die alle *überhaupt* auf das Objekt gehören.
`__getitem__()` ist falsch implementiert. Das muss den Wert *zurück-* und nicht *aus*geben. Und das ist in der Regel zusammen mit `__setitem__()` in der Regel auch der Ort wo die Koordinaten „vertauscht“ werden, damit die Daten weiterhin als Sequenz von Zeilen repräsentiert werden können. Diese interne Darstellung zu transponieren, macht den Rest des Programms nur umständlicher.
`__setitem__()` sollte keinen Wert zurück geben. Der Rückgabewert wird sowieso „verschluckt“.
Die `__str__()` ist nur so kompliziert, weil Du die interne Darstellung transponiert hast. Sonst wäre das ein Einzeiler ohne die ganzen gruseligen Indexe und das ``for i in xrange(len(obj)):``-Anti-Pattern. Das ist kein idiomatisches Python.
Das gleiche gilt für `getStart()` und `getFinnish()`. Man kann über Elemente in Listen *direkt* iterieren, ohne einen Umweg über einen Index zu gehen. Falls man den Index *zusätzlich* benötigt, gibt es die `enumerate()`-Funktion.
Die „magischen“ Methoden sollte man nicht direkt aufrufen, wenn man nicht muss. Für `__str__()` sollte das nie der Fall sein.
Ein `sys.exit()` in einer Methode die einen allgemeinen Algorithmus implementiert ist der Hammer. Stell Dir mal vor die Aufgabe würde ganz leicht anders lauten: Lösen sie alle Labyrinthe in Verzeichnis ``spam/``. Normaler Code sollte niemals das Programm einfach so beenden.
Laut Aufgabenstellung soll `solve_maze()` als Funktion implementiert werden.
`suggest_dir()` solltest Du das `maze`-Exemplar übergeben und nicht die interne Repräsentation des selben. Und wenn Du die `__getitem__()` reparierst, dann kannst Du auch über den Index-Operator auf die Felder zugreifen und musst nicht überall über die interne Repräsentation gehen.
Bei Containerobjekten sind leere Container im Wahrheitskontext falsch. Das wird üblicherweise auch ausgenutzt, also statt ``if len(things) == 0:`` schreibt man ``if not things:``.
Last but not least funktioniert der Code so nicht, weil bereits besuchte Felder nicht wieder freigegeben werden, man also am Ende mehr als den Pfad mit '.' markiert haben kann.
Die Module `time` und `threading` scheinen nirgends verwendet zu werden!?