/
niemand.leermann@thomas-guettler.de
Python, Programmieren macht Spaß
1 Einführung
[toc]
-
Python ist eine leicht zu lernende,
objektorientierte Programmiersprache.
-
Plattformunabhängig: Windows, Unix und Mac
-
Interpretierte Sprache (Script-Sprache)
2 Wie bin ich zu Python gekommen?
[toc]
- Vor dem Studium: BASIC (C64), etwas Assembler, Turbo Pascal.
- Während dem Studium: Unix-Shell, C, C++, Java, Prolog, Lisp, Visual Basic.
- In der Freizeit: Perl
- Keine der Programmiersprachen machte mir wirklich Spaß.
- 2001: Suche nach Alternative: Ruby oder Python. Ruby ohne integrierte Unicode Unterstützung (bis heute)
- Seit 2001: arbeitstäglich Python.
3 Begeisterung
[toc]
-
Die Programmiersprache Python bietet sehr viele Bibliotheken. Die
Module aus der Standardbibliothek werden gut gepflegt.
-
Man bekommt bei Fehlern immer einen Stacktrace mit Zeilennummer des
Fehlers. In "C" muss man dafür extra den Debugger starten.
-
Segmentation Faults sind nicht möglich --> Programmentwicklung ist
schneller als in C oder C++.
-
Die Entwicklungsgeschwindigkeit ist heutzutage wichtiger als die
Ausführungsgeschwindigkeit zur Laufzeit. Zeitkritische Abschnitte
können in C oder C++ geschrieben werden.
-
Sehr schön ist, dass man keine Makefiles mehr braucht. Die
vorkompilierten PYC-Dateien (Bytecode) werden automatisch neu
erstellt, falls sich die zugehörige PY-Datei geändert hat.
-
Python verfügt über eine einfache Entwicklungsumgebung: IDLE. Das ist ein Vorteil
für den Unterricht und Schulungen, da nicht zusätzlich ein Editor
installiert werden muss.
-
Die Python Newsgroups sind sehr anfängerfreundlich. Jeder Python
Programmierer sollte hin und wieder hineinschauen. Man lernt immer
dazu.
- Die Lizenz ist nicht GPL. Python lässt sich ohne Probleme
auch in kommerziellen (closed Source) Projekten verwenden. Siehe Python Licence.
- Die Programmiersprache ist stabil. Änderungen die nicht
abwärtskompatibel sind, sind innerhalb der Majorversion (2.x, 3.x)
nicht zu erwarten.
- Die Schlüsselworte und Funktionen heißen meist enstsprechend dem
ANSI-C, bzw. POSIX Standard. Erfahrende Programmierer finden sich
schnell zurecht.
4 Vorbereitung für Workshops
[toc]
Kursteilnehmer sollten vor dem Workshop:
- In der Lage sein englischsprachige Dokumentation zu verstehen.
- Sich mit einem Texteditor auskennen (Emacs, vim, gedit, IDLE, ...)
- WLAN am Laptop einrichten
- Python installieren
- Python Doku installieren oder per Web: docs.python.org Library Reference
- Interaktiven Interpreter aufrufen ... dort zB help(list) oder rechnen: (5+10**5)*2
5 Beispiel: Taschenrechner
[toc]
-
Dank der Readline-Bibliothek kann man den Interpreter sehr bequem
interaktiv benutzen.
-
Beispiel: Verwendung von Python als Taschenrechner.
Aufgabe: Wenn ich ein 56k Modem habe, wie lange dauert es eine 8MB Datei
herunterzuladen?
- Code:
==guettli@sonne:~$ python
Python 2.5.1 (r251:54863, Oct 5 2007, 13:36:32)
[GCC 4.1.3 20070929 (prerelease) (Ubuntu 4.1.2-16ubuntu2)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> bps=56000 # Bit pro Sekunde
>>> byte_pm=(bps/8)*60
>>> byte_pm
420000
>>> datei=8*10**6 # acht mal zehn hoch sechs
>>> dauer=datei/byte_pm
>>> dauer
19
--> Es dauert rund 19 Minuten
6 Datentypen
[toc]
6.1 Übersicht
[toc]
| Integer |
i=1 |
Ganzzahl |
| Float |
f=0.1 |
Gleitkommazahl |
| String |
s='hallo' |
Zeichenkette |
| Liste |
l=[1, 2, 3] |
Veränderbare Liste |
| Tuple |
t=(1, 2, 3) |
Unveränderbare Liste |
| Dictionary |
d={1: 'eins', 2: 'zwei', 3: 'drei'} |
Auch Hash oder assoziatives Array genannt. |
6.2 Zahlen
[toc]
Es gibt die Datentypen Integer/Ganzzahlen (int), Float/Gleikommazahlen
sowie Dezimalzahlen belieber Genauigkeit.
i=1 # Zuweisung
i+=1 # i++ wie in C gibt es nicht
i*=2
i**2 # i "hoch" 2
docs.python.org: Operatortabelle: Numeric Types
6.3 Zeichenketten
[toc]
-
Strings (Zeichenketten) sind eine Folge von Zeichen. Man muss sich
nicht um die Terminierung von Zeichenketten, wie z.B. in C kümmern.
- Zeichenketten können in einfachen oder doppelten
Anführungszeichen geschrieben werden. Mehrzeilige Zeichenketten sind
durch dreifache Anführungszeichen möglich:
s1='Beispiel'
s2='Er sagte "Hallo" zu mir'
s3="er ist der 20'te"
s4="""Mehrere Zeilen
Zeile 2
Zeile 3
"""
s5='''Ebenfalls mehrere
Zeilen
'''
- Die Formatierung wie mit printf in C ist möglich:
s='Sonne'
m='Mond'
t='Sterne'
satz='%s, %s und %s' % (s, m, t)
--> Sonne, Mond und Sterne
# Formatieren von Gleitkommazahlen:
f=0.123456
s='%06.2f' % f
# Ergebnis: 000.12
# Einfügen über ein Dictionary
import time
heute=time.strftime('%d.%m.%Y')
title='Das ist der Titel' # Wird zweimal verwendet.
# Im Kopf, und als <h1>
html='''
<html>
<head>
<title>%(title)s</title>
</head>
<body>
<h1>%(title)s</title>
...
Heute ist der %(heute)s
....
</body>
</html>''' % locals()
docs.python.org: String Formatierung
- Zeichenketten können auch getrennt werden, um z.B.
den Quellcode nicht breiter als 80 Zeichen zu machen. Die
Variablensubstitution funktioniert trotzdem:
print('Text ......Wert1 = %s '
'Wert2 = %s '
'Wert3 = %s ' % (
wert1, wert2, wert3))
- Slices (Aus einem Teilbereich einer Liste eine neue Liste erstellen)
s='abcdefg'
#Erstes Zeichen
s[0] # --> 'a'
#Letztes Zeichen
s[-1] # --> 'g'
#Zugriff auf Teile der Liste
s[:4] # --> 'abcd'
s[1:4] # --> 'bcd'
s[-2:] # --> 'fg'
-
Zeichenketten können, sollten aber nicht, mit dem Plus Operator
verbunden werden. Es ist effizienter mit einer Liste zu arbeiten:
s=[]
for i in range(10):
s.append(str(i))
s=''.join(s)
assert s=='0123456789'
- Die in C üblichen Sonderzeichen sind vorhanden:
\n == Newline (Zeilenumbruch)
\r == Carriage Return
\t == Tabulator
\\ == Backslash
Möchte man das Interpretieren der Escape Sequenzen unterbinden,
kann dies durch ein vorangestelltes 'r' geschehen.
s = 'a\nb' # --> \n wird zu einem Newline
s = r'a\nb' # --> \n wird *nicht* zu einem Newline
- Weiteres
-
#Länge
len(s)
-
# Substring
if 'oma' in 'Thomas':
....
-
#Auftrennen an Leerzeichen:
satz='Aller Anfang ist schwer'
satz.split() # --> ['Aller', 'Anfang', 'ist', 'schwer']
-
dateiname='foo.PNG'
if dateiname.lower().endswith('.png'):
....
-
# Ist das eine Zeichenkette?
if isinstance(myvar, basestring):
print 'ja, das ist ein String'
- Unicode
unicode_string=u'üöäßÜÖÄ'
print len(unicode_string) # Länge: 7
byte_string=unicode_string.encode('utf8') # Wandeln von Unicode-Zeichenkette zu Bytefolge
print len(byte_string) # Länge: 14
byte_string.decode('utf8') # Wandeln von Bytefolge zu Unicode-Zeichenkette
Einfaches Recode Script in Python: pyrecode
Achtung: Im interaktiven Interpreter ist das Encoding deiner Eingaben
nicht definiert. Darum mit einer Python-Datei arbeiten, und das
Encoding angeben: # -*- coding: utf-8 -*-
Anstatt vieler decode-Aufrufe, lieber
codecs.open('foo.txt', 'rt', 'latin1) verwenden (wenn man
weiß, dass die Datei in latin1 ist), dann liefert fd.read()
Unicode-Objekte.
docs.python.org: Operatorentabelle für Sequenzen (Tuple, List, String, ...)
docs.python.org: Methoden von Strings
6.4 Listen
[toc]
-
Strings und Tuples sind 'immutable', d.h. sie können
nicht verändert werden. Listen sind im Gegensatz dazu veränderbar.
-
Es können beliebig Listeneinträge hinzugefügt oder entfernt werden.
Die Länge muss nicht wie in vielen anderen Programmiersprachen vorher
definiert werden.
- Der erste Eintrag in einer Liste wird mit einer Null angesprochen.
- Code:
mylist=['Das', 'Wetter']
mylist.append('schön')
mylist[1]='Leben'
mylist.insert(2, 'ist')
print mylist # Das Ergebnis?
- Listen von Listen
mylist[1]=[3, 4]
- Schleife über 3'er Tupel
zahlen=[(1, 'eins', 'one'),
(2, 'zwei', 'two'),
(3, 'drei', 'three')]
for i, deutsch, englisch in zahlen:
...
docs.python.org: Operatortabelle: Mutable Sequence Types
6.5 Dictionaries (Hash-Tables)
[toc]
-
Dictionaries sind ein wichtiger Datentyp, der die tägliche Arbeit
vereinfacht. Dictionaries bestehen aus einen Schlüssel (Key) und
einem zugeordneten Wert (Value). Hier ein Beispiel, wie man
Telefonnummern verwalten kann. Die Keys sind Zeichenketten (die
Namen) und die Values sind die Telefonnummern.
- Code:
mydict={}
mydict['hans']='030/312783'
mydict['bernd']='0921/76499'
mydict['susi']='0371/233444'
print 'Hans: ', mydict['hans']
print 'Das Telefonbuch: ', mydict
#Alle Einträge ausgeben:
for name, nummer in mydict.items():
print 'Name: %s Nummer: %s' % (name, nummer)
- Funktionen
| mydict.keys() |
[key1, key2, ...] |
Alle Schlüssel |
| mydict.values() |
[value1, value2, ...] |
Alle Werte |
| mydict.items() |
[(key1, value1), (key2, value2), ...] |
Liste von 2er Tuples |
| mydict.has_key(key) |
True oder False |
Ist dieser Schlüssel vorhanden? |
| mydict.get(key1, default)
| value1 oder default |
Wert von 'key1', falls nicht vorhanden,
wird 'default' zurückgegeben.
|
- Dictionaries sind nicht sortiert!
docs.python.org: Operatortabelle: Mapping Types
7 Sonstiges
[toc]
Folgende Schlüsselworte haben eine besondere Bedeutung:
| True | Boolscher Wert für Wahr |
| False | Boolscher Wert für Falsch |
| None | Leerer Wert, NIL, Null-Pointer |
8 Flusssteuerung
[toc]
-
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys
print('Bitte Zahl eingeben:')
input=sys.stdin.readline()
input=input.strip() # Newline (\n) am Ende der Eingabe entfernen
i=int(input)
if i<0:
print '%s ist kleiner als Null.' %i
elif i==0:
print '%s ist gleich Null.' % i
else:
print '%s ist größer als Null.' % i
- Die Blockstruktur wird durch das Einrücken mit vier Leerzeichen
gekennzeichnet (Tabs sollten nicht verwendet werden):
for x in [1, 2, 3, 4]:
print x
for x in range(6):
if x==1:
# Überspringe diese Zahl
continue
if x==4:
# Beende die Schleife
break
print x
- While-Schleife:
mylist=[1, 2, 3, 4]
while mylist:
print mylist.pop()
9 Funktionen
[toc]
-
Funktionen werden durch das Schlüsselwort 'def' definiert:
def plus(a, b):
return a+b
print plus(5, 7)
--> 12
- Parameter werden Call By Assignment übergeben. Beim
Funktionsaufruf werden die Parameter den lokalen Variablen
zugewiesen. Entsprechend werden Integer, Float und Zeichenketten
"call by value" und Objekte werden "call by reference" übergeben.
def fuelleListe(liste):
liste.append('eins')
liste.append('zwei')
liste.append('drei')
liste=[]
fuelleListe(liste)
print liste
--> ['eins', 'zwei', 'drei']
- Default Argumente:
def printEtwas(etwas='Gurkensalat'):
print etwas
printEtwas()
--> Gurkensalat
printEtwas('Tomatensuppe')
--> Tomatensuppe
- Keyword Arguments:
Argumente die per Schlüsselwort gesetzt werden
sind sehr nützlich, da man sich bei Funktionen mit vielen Parametern
schlecht die Reihenfolge merken kann:
def berechneWiderstand(volt, ampere):
return float(volt)/ampere
print berechneWiderstand(volt=12, ampere=4)
print berechneWiderstand(ampere=4, volt=12)
10 Python-Datei
[toc]
Ein Python Script wird in einer Datei gespeichert, die mit ".py"
endet. Als Vorlage kann folgende Datei dienen: reverse.py
Wie führt man nun dieses Programm aus?
Unter Unix ruft man es von der Shell auf:
python myscript.py
Steht in der ersten Zeile #!/usr/bin/python und hat man die
Ausführungsrechte gesetzt (chmod a+rx myscript.py) kann man es direkt
ausführen:
./myscript.py
Unter Windows kann man ein Script durch Doppelklick aus dem
Explorer ausführen. Endet die Datei mit ".py" wird es in einer
MS-DOS Eingabeaufforderung ausgeführt. Wenn es die Endung ".pyw" hat,
wird es ohne zusätzlichem Fenster gestartet. Der Nachteil vom
Anklicken ist, das man dem Script keine Argumente übergeben kann. Zur
Not kann man das Script aus der MS-DOS Eingabeaufforderung aufrufen
und dort Argumente übergeben.
Startet man ein Programm durch Doppelklick auf eine .py Datei,
schließt sich das Fenster sobald das Script beendet ist. Möchte man,
dass das Fenster offen bleibt, kann man ein "sys.stdin.readline()" am
Ende einfügen.
Ein typischen Programm in Python:
#!/usr/bin/python
# -*- coding: utf-8 -*-
# Python Imports
import os
import sys
def usage():
print '''Usage: %s
....
''' % (
os.path.basename(sys.argv[0]))
def main():
if len(sys.argv)==1:
usage()
sys.exit(3)
if __name__=='__main__':
main()
Die Funktion "main" wird aufgerufen, wenn das Script aufgerufen
wird.
Wird das Script von einer anderen Datei importiert (import
myscript), wir die Main-Funktion nicht aufgerufen. Es werden dann nur
die Funktionen und Klassen bereitgestellt.
11 Dateien
[toc]
12 Klassen - Objektorientierung
[toc]
-
Klassen sind Datenstrukturen, die aus Methoden und Attributen bestehen.
Methoden sind Funktionen einer Klasse, und Attribute sind Daten einer
Klasse. Ein Beispiel: klasse-auto.py
-
Python unterstützt auch Vererbung, sowie Mehrfachvererbung und
Exceptions.
- Alle Methoden und Attribute sind 'public'. Beginnt der Name mit
einem Unterstrich, ist das nur ein Hinweis, dass darauf von außen
nicht zugegriffen werden soll.
13 Standardbibliothek
[toc]
13.1 Module importieren
[toc]
Ein Modul (bzw. Bibliothek) wird mit der import-Anweisung
eingebunden. Die Funktionen, Variablen und Klassen dieses Moduls sind
über den Modulnamen anzusprechen.
import sys
sys.argv[0] # Scriptname
from xml import sax
sax.parse(...)
13.2 Paketauswahl
[toc]
Folgende Pakete gehören zur Standardbibliothek und sind in der Regel
immer vorhanden. Da die gesamte Liste der Python Pakete inzwischen
recht lang geworden ist, will ich hier die aus meiner Sicht
wichtigsten Pakete aufzählen:
- re:
Python unterstützt reguläre Ausdrücke (Regular Expressions). Es
wird die Bibliothek PCRE (Perl
Compatible Regular Expressions) verwendet.
- sys:
Sys enthält unter anderem:
sys.exit() sofortiges Beenden des Programms
sys.stdin, sys.stdout, sys.stderr
sys.argv Liste der Argumente beim Programmaufruf.
Der Scriptname steht in sys.argv[0]
- pickle:
Pickle (Serialisieren) bedeutet, dass man Datenstrukturen zu
einer Bytefolge konvertiert. Diese Bytes können dann in einer Datei
gespeichert werden. Für kleine Programme kann man somit der Einsatz einer
Datenbank vermieden werden.
import pickle
dict={}
dict['hans']='0815'
dict['gerd']='007'
fd=open('datei.pickle', 'w')
#Speichern der Daten
pickle.dump(dict, fd)
fd.close()
# Die Pickle-Datei ist reines ASCII
Laden des Dictionaries aus der Datei:
import pickle
fd=open('datei.pickle')
dict=pickle.load(fd)
fd.close()
print dict
- os:
Betriebsystemfunktionen (meist entsprechend POSIX):
os.system(), os.chdir(), os.getcwd(), os.nice(), os.kill(),
os.chmod(), os.environ['PATH'],
os.walk() (ähnlich wie 'find')
- datetime:
Datumsfunktionen, besser als das Modul "time", da nicht nur in der
Einheit "Sekunden seit 1970" gerechnet wird.
- urllib: Öffnen von Dateien per http://... oder ftp://...
- cgi:
Einfache CGI-Schnittstelle.
- cgitb: Falls in einer Webanwendung ein Fehler auftritt,
kann man mit cgitb eine HTML Seite erzeugen lassen, die sehr viele
Informationen enthält die zur Fehlersuche hilfreich sind (lila
Seiten). Man kann sich auch einen eigenen "Handler" schreiben, der
einem die Fehlermeldung automatisch per E-Mail zuschickt: cgitb.html
- poplib, imaplib, smtplib
- email: Emails im MIME-Format bearbeiten.
- xml.sax, xml.dom, xml.etree.ElementTree
- Kryptography: md5, sha
- subprocess:
Sicheres Ausführen von Prozessen. Werden Variablen in einem
Systemruf verwendet, die aus unsicherer Quelle stammen
(CGI-Umgebung), ist das Verwenden von os.system() oder os.popen()
eine Sicherheitslücke.
Beispiel:
form=cgi.parse()
# Test ob Rechner 'hostname' per Ping erreichbar ist
ret=os.system("ping -c1 '%s'" % form.getfirst('hostname'))
--> Achtung: Ein Angreifer kann "myhost'; rm -rf /" übergeben!
Besser:
import subprocess
cmd=['ping', '-c1', form.getfirst('hostname')]
ret=subprocess.call(cmd)
--> Es wird direkt Ping und nicht erst eine Shell aufgerufen.
14 Externe Bibliotheken
[toc]
- pyGTK:
Python Anbindung an die GUI-Bibliothek GTK.
- Django:
Web-Framework. Siehe auch Django Einführung. (Das Modul cgi reicht für kleine CGI-Scripte)
- DB-API:
Anbindung an relationale Datenbanken: PostgreSQL (psycopg2), MySQL, Oracle, ...
- epydoc:
Erstellt API-Dokumentation anhand von Kommentaren im
Quelltext. Ausgabeformate sind HTML oder Latex.
15 Beispiele
[toc]
16 Externe Links
[toc]
16.1 Internet
[toc]
16.2 Best of Python Cookbook
[toc]
Hier einige "Rezepte" aus dem Python Cookbook:
17 Nachteile von Python
[toc]
Einige Dinge sind auch an Python nicht optimal:
- Für Programmierer die vorher mit Visual Basic, Delphi oder Visual
C++ gearbeitet haben, ist der Einstieg in Python ernüchternd: Die
mitgelieferte Entwicklungsumgebung IDLE ist nicht geeignet um
grafische Benutzeroberflächen "zusammenzuklicken". Außerdem gibt es
keine Intelli-Sense (automatische Namenserweiterung).
Auf den zweiten Blick ist es jedoch eine logische Trennung
von unabhängigen Teilen: Der Quelltext kann mit jedem beliebigen
Editor erstellt werden (Emacs, vim, Ultra-Edit, Kate usw.) und
grafisch Benutzeroberflächen können mit dem jeder beliebigen
GUI-Bibliothek erstellt werden (gtk, tk, qt usw.).
- Python macht faul: Wenn man mit der Syntax von Python und der
umfangreichen Standardbibliothek vertraut ist, möchte man meist nicht mehr
andere Sprachen verwenden.
- Kein Standard Web-Framework: Für Python gibt es sehr viele
Web-Frameworks. Es ist schwer das Richtige zu finden. Ich persönlich
mag Django.
18 Vergleich mit anderen Programmiersprachen
[toc]
Siehe Vergleich von mir bekannten Programmiersprachen
19 Hinweise zur Python Programmierung
[toc]
- "from foo import *" sollte vermieden werden.
- Wenn aus verschiedenen Quellen Module benutzt werden, ist es
übersichtlich, wenn man die Import-Anweisungen zusammenfasst:
#Python Imports (Standard Library)
import os
import re
#Gtk Imports (Externe Library)
import gtk
#My Imports
import myPackage
- Mit Assertions kann man überprüfen, ob die gerade zu bearbeiten
Daten konsistent sind: Wenn eine Variable z.B. nur Integerwerte
enthalten sollte:
assert isinstance(mydict, dict), 'Variable mydict ist kein Dictionary: %r' % mydict
Guter, robuster Quelltext enthält viele Assertions.
21 Python++
[toc]
Folgende Abschnitte sind für Fortgeschrittene.
21.1 List Comprehension
[toc]
# Mit einer Schleife Leerzeichen am Anfang/Ende entfernen.
fruechte=[' Apfel ', ' Banane ', ' Kiwi ', ' Ananas']
neue_fruechte=[]
for frucht in fruechte:
frucht=frucht.strip()
neue_fruechte.append(frucht.strip())
fruechte=neue_fruechte
# List Comprehension
fruechte=[frucht.strip() for frucht in fruechte]
21.2 Properties
[toc]
class Zahl(object):
def __init__(self, i):
self.i=i
def get_next(self):
return self.i+1
next=property(get_next)
zahl=Zahl(2)
print zahl.next # --> 3
Impliziter (versteckter) Funktionsaufruf. Es wird auf die Eigenschaft
(das Attribut) 'next' zugegriffen. Im Hintergrund wird die
Getter-Funktion get_next() aufgerufen. Siehe docs.python.org: Built-in Function property
21.3 Decorator
[toc]
Mit einem Decorator wird eine Funktion 'verkleidet'. Folgendes
Beispiel implementiert den Decorator 'commit_on_success'.
#!/usr/bin/python
# -*- coding: utf-8 -*-
def begin():
print 'begin'
def commit():
print 'commit'
def rollback():
print 'rollback'
def commit_on_success(func):
'''
Führe commit() aus, falls die dekorierte Funktion keine Exception
wirft. Ansonsten wird rollback() aufgerufen.
'''
def _commit_on_success(*args, **kw):
begin()
try:
res = func(*args, **kw)
except Exception, e:
rollback()
raise # Re-raise (aufgefangene Exception erneut werfen)
else:
commit()
return res
return _commit_on_success
@commit_on_success
def foo(do_raise):
if do_raise:
raise Exception()
foo(False) # --> commit()
foo(True) # --> rollback()
'''
===> python deco.py
begin
commit
begin
rollback
Traceback (most recent call last):
File "tmp/deco.py", line 32, in <module>
foo(True) # --> rollback()
File "tmp/deco.py", line 17, in _commit_on_success
res = func(*args, **kw)
File "tmp/deco.py", line 29, in foo
raise Exception()
Exception
'''
21.4 Generators
[toc]
Generatoren verhalten sich wie Listen. Es wird 'on-the-fly' für jeden
Schleifendurchlauf das aktuelle Element zurückgegeben. Dieses
Verfahren verbraucht weniger Hauptspeicher. Hier eine Nachbildung der
Funktion xrange():
def myxrange():
i=0
while True:
yield i
i+=1
for i in myxrange():
print i
if i==5:
break
Siehe auch docs.python.org: Iterator Types
und docs.python.org: The yield statement
22 Debugging Tipps
[toc]
Hier einige Hinweise zum Auffinden von Fehlern:
- Abarbeitung abbrechen und Variablen anzeigen:
....
assert False, (var1, )
# Erklärung: Wenn der Interpreter auf diese Anweisung stößt, wird eine Exception
# geworfen und das Tuple von Werten wird angezeigt.
- Quelltext mit Assert-Anweisungen 'spicken':
var=func()
assert isinstance(var, int), 'var (%s) is kein Integer, sondern %s' % (var, type(var))
# Erklärung: Falls die Variable nicht vom Typ Integer ist, wird ein Exception
# geworfen und eine entsprechende Warnung angezeigt.
- Aktuellen Stack ausgeben:
import traceback
print ''.join(traceback.format_stack())
# Erklärung: Wenn man weiß wo ein Fehler auftritt, aber nicht weiß welche
# Stellen die Funktion aufrufen, sieht man die verschachtelten Funktionsaufrufe,
# die zum Ausführen der entsprechenden Zeilen führten.
-
import logging
logging.error('Fehler ... var=%s' % var)
# Siehe docs.python.org: logging
Diese Seite entstand im Rahmen folgender Vorträge und Workshops:
Wem diese Seite geholfen hat, kann mir gerne ein Buch aus meinem Amazon Wunschzettel schenken.
© 2002-2012 Thomas Güttler. Der Text darf nach belieben
kopiert und modifiziert werden, solange dieser Hinweis zum
Copyright und ein Links zu dem Original unter www.thomas-guettler.de
erhalten bleibt. Es wäre nett, wenn Sie mir Verbesserungsvorschläge
mitteilen:
guettli@thomas-guettler.de