|
|
Weitere Tips, Ratschläge und Hinweise |
|---|
|
Beim schrittweisen Kennenlernen von Python bin ich immer wieder überrascht worden. Das waren teilweise angenehme Überraschungen (es ging irgendwas besser, als ich erwartet hatte), aber es gab auch vorerst unverständliche Dinge, die teilweise erst nach einiger Arbeit eingegrenzt werden konnten. Die letzteren sollen hier als helfender Ratschlag vermerkt werden. Wenn man den doc-String (der mit "''' eingeschlossen ist) mit idle ansehen will, sollte man print modulname.__doc__ eingeben (nicht ohne print, sonst geht auf
dem Screen alles durcheinander!). Die Funktionen in dem Modul msvcrt (hier ist es mir mit der Funktion "kbhit" aufgefallen), die für den Pythoneinsatz unter Windows vorgesehen sind, funktionieren anscheinend nicht unter der idle, sondern nur im Kommandofenster! Durch das das print-scolling steht der Kursor auf der vollgeschriebenen Seite immer unten und schiebt bei weiteren Ausgaben alles nach oben. Will man den Bildschirm mal wieder aufräumen, hilft:
import os a fängt den Rückgabewert ab, der sonst auf dem Bildschirm erscheint range() geht auch mit einem einzigen Argument. Dann geht es jeweils bei 0 los. Ist das Argument 1, dann entsteht [0]. Ist das Argument kleiner als 1, entsteht [] Es gibt Schwierigkeiten, wenn man ein Modulname einen Bindestrich enthält. Anscheinend wird das dann beim Aufruf des Moduls so interpretiert, als wenn Parameter folgen würden. Folgender Hinweis gilt, wenn man aus bestimmten Gründen
gezwungen ist, mit einer älteren Version von Python zu arbeiten
und dabei auf die Idle zurückgreift: Wenn man dann ein Python-Modul, das unter Windows entwickelt wurde, auch unter Linux einsetzten oder weiterentwickeln will, müssen vorher die Windows/DOS - typischen Wagenrückläufe \r entfernt werden. Dies ist mir zumindest passiert, als ich ein solches Modul unter Idle mit Linux starten wollte. Promt kam eine Fehlermeldung und die \r waren im Editor auch sichtbar. Ein Tupel ist unveränderlich, d.h. ich kann seine Elemente nicht durch Zuweisung ändern. So bringt z. B. t = (100, 200) sofort eine Fehlermeldung. Aber Achtung! Enthalten die
Elemente des Tupels selbst Veränderliche, dann geht
es trotzdem! L1 = ['europa', 'asien'] dann geht es, mit t[1][0] = 300 zuzuweisen. Allerdings ist das
Ergebnis nicht etwa t = (L1, 300) sondern t = (['europa', 'asien'], [300]) Eine ähnliche Überraschung wartet auf uns bei der Parameterbehandlung durch Funktionen. Die Parameterübergabe erfolgt "call by reference", d.h. die Funktion erhält eigentlich einen Zeiger (Adresse) auf die übergebene Variable. So steht es jedenfalls in den Pythonbüchern, die etwas über die Interna von Python verraten. Als alter Pascalanhänger ist man geneigt, sofort die klassischen Schulbeispiele dazu auszuprobieren, die man damals gezeigt bekam um den Unterschied der Variablenübergabe direkt oder mit "var" gegenüberzustellen. Probieren wir doch einfach selbst: 1. Einfaches Objekt a = 100 def set(x): set(a) bringt nach dem Start: >>> 100 Nanu, stimmt da etwas nicht? Wir hatten
doch jetzt erwartet, dass der Wert von a sich auf 2 geändert
hätte. Erfolgt die Variablenübergabe etwa doch auf die Weise,
dass eine Kopie der Variablen angelegt wird, die dann zwar intern
verändert werden kann aber nach draußen keine
Veränderung bewirkt? Das wäre nämlich eine
Parameterübergabe call by value und die Lehrbücher
hätten sich alle geirrt !! Probieren wir sicherheitshalber etwas
ausführlicher:
def tausch(x, y): >>> 100, 200 aha,
also geht es doch! Die neuen Werte müssen natürlich auch nach
der Behandlung in der Funktion nach draußen transportiert werden.
Dafür funktioniert aber die Vorgehensweise im Versuch 1 bei
veränderlichen Objekten: 3. Veränderliches Objekt a = [1, 2, 3] def set(x): set(a) bringt nach dem Start: >>> [2, 2, 3] Die Funktion hat hier also auch ohne besondere Maßnahmen in die aufrufende Umgebung gegriffen. Slicing geht auch mit Strings, die in Listen geordnet sind. So ist z.B. >>> L = ['Hallo', 'Berlin', 'Deutschland'] >>> L[1][0:-1] 'Berli' Das läßt sich z.B. anwenden, wenn man aus einem
File mit readlines alle Textzeilen in eine Liste
eingelesen hat, und sich danach ärgert, dass alle
Zeilen mit einem Zeilenendezeichen versehen sind. Dann
kann mit Slicing genau das letzte Byte beim Zugriff
jeweils entfernt werden. Bei der Division von Integerzahlen werden entstehende Dezimalstellen abgeschnitten. So bringt z.B. >>> min = 59 Noch überraschender wird es, bei negativen Zahlen: >>> -3/2 Hier wird auf die nächstgrößere Zahl (in negativer Richtung) hin gerundet!! Möchter man gern, dass das Ergebnis genauer herauskommt, hilft ein kleiner Trick: >>> min/60.0 Da im Quotient nicht alle Zahlen Integer sind, kommt als Ergebnistyp float heraus. Man muß es nur wissen. Typenvergleich Mit der Funktion type() lässt sich feststellen, von welchem Typ eine Variable ist. Beispiel: >>> print type('#')
Um nun eine Fallunterscheidung zwischen verschiedenen Typen zu machen, weil davon abhängt, wie ein Wert weiterverarbeitet wird (wir durchmustern z.B. ein Tupel, dessen Elemente ja sonst was sein können und nicht jede Operation geht auf jeden Typ anzuwenden) gibt man zum Vergleich natürlich nicht so ein Konstrukt ein, wie die type - Funktion liefert, sondern man nimmt einfach einen elemntaren vertreter seiner Klasse. Beispiel, wir wollen prüfen, ob a vom Typ integer ist: if type(a) == type(1): oder wir vergleichen, wenns um Strings
geht, mit type('') usw. |