Letzter Update: 2009-07-25
KnowHow - Software - Python - Kurz
Ich mag die Dinge ultrakurz als Übersicht, setzt mindestens Python 2.4 voraus. Ab Python 2.5 gibt es wesentliche Verbesserungen bei Iteratoren, wodurch Coroutinen erst möglich werden.
Minimalprogramm
Ein kleines Python-Programm das einen guten Anfang abgibt:
#!/usr/bin/env python
def main(arg):
print "Hello world and %s" % arg
if __name__=='__main__':
import sys
if (len(sys.argv)!=2):
raise "Single argument please"
main(sys.argv[1])
Typen
Python hat neben den normalen Typen auch viele "Collection"-artige Datentypen:
tuple (1,) immutabel (nicht der Inhalt, aber das tupel selbst)
list [1] mutabel
dict {0:1} mutabel
- Tupel sind in der Regel schneller als Lists.
Wichtig: Man kann die einfach addieren:
(1,)+(2,)
[1]+[2]
aber nicht
{0:1}+{1:2}
Oft wird man folgendes Konstrukt finden:
args={'param':wert}
fn1(**args)
fn2(*args)
parms=(wert,)
fn3(*parms)
Das ist gleichwertig zu
fn1(param=wert)
fn2(wert)
fn3(wert)
Funktionen kennen notwendige (x), unbenannte (y) und benannte (z) parameter. Die notwendigen Parameter werden mit den unbenannten Parametern von vorne aufgefüllt, die unbenannten (y) bekommen alle weiteren unbenannten Parameter zugewiesen:
def test(x,*y,**z):
print repr(x)
print repr(y)
print repr(z)
test(1,2,3)
test(1,a=1)
test(x=1)
aber nicht
test(1,x=2)
test(a=1)
test(y=(1,))
test(x=1,27)
Die Reihenfolge ist zu beachten, zuerst unbenannte, dann benannte. Und die bereits besetzten Keywörter kann man nicht überschreiben.
Immutable
Strings "string" 'string'
Zahlen (übliches)
Komplexe Zahl 1+2j complex(1,2)
Tupel (1,) manchmal auch ohne Klammern schreibbar, aber: Der Inhalt kann mutabel sein!
"""multi (ginge auch mit ')
line
strings"""
Spezial: Erster String (normalerweise Multi-Line) in Funktion/Modul etc. ist Variable __doc__
Immutable Sets
Frozensets sind spezielle Tupel die Werte nur einmal enthalten. Sie können nur Werte enthalten die immutable sind (d. h. unveränderlich), da sie selber unveränderlich sind. (s und t sind sets)
frozenset(list) Erzeuge ein Frozenset
s-t s.difference(t) Elemente die in s sind aber nicht in t (s ohne t)
s|t s.union(t) Vereinigungsmenge: Elemente die in s oder t sind (aber nur einfach!)
s&t s.intersection(t) Schnittmenge: Elemente die sowohl in s als auch in t sind
s^t s.symmetric_difference(t) Vereinigung ohne Schnitt: (s|t)-(s&t)
s<=t s.issubset(t) s ist in t enthalten
s>=t s.issuperset(t) t ist in s enthalten
s.copy() Flache Kopie
Werden Sets und Frozensets gemischt bestimmt der erste Operand (links) den Resultatstyp.
Mutable
List [a,b]
Dictionary {i1:v1, i2:v2}
set(list) Erzeuge ein Set
s|=t s.update(t) s=s|t
s&=t s.intersection_update(t) s=s&t
s-=t s.difference_update(t) s=s-t
s^=t s.symmetric_difference_update(t) s=s^t
s.add(x) s=s|set([x])
s.remove(x) s=s-set([x]) allerdings mit Exception KeyError wenn x nicht in s ist.
s.discard(x) s=s-set([x]) (ohne KeyError)
s.pop() holt ein (beliebiges) Element aus s, KeyError wenn leere Liste
s.clear() s=set()
Funktionen und Listen
Sets,Listen und Assoc sind Collections,
l=[1,2,3] wenn unten verwendet war es vorher so gesetzt
x in l Testet ob x in l enthalten ist
x not in l Testet ob x nicht in l enthalten ist
complex(a,b).real=a complex(a,b).imag=b
abs(complex(a,b)) "Länge" der komplexen Zahl: sqrt(a*a+b*b)
"hello"[1:2] Ergibt "e", denn from:to index ab 0 und exklusive "to"
"hello"[-1] "o" (vom Ende)
del var funktioniert auch für del a[5]
"a"*3 "aaa"
"%03d" % 3 "003" (wie sprintf)
len("test") 4 strings sind eigentlich nur Listen aus Bytes
len((2,)) 1 Anzahl der Elemente im Tupel
len([a,b]) 2 Geht auch für Listen, etc.
l[1]=[5,6] [1,[5,6],3] Extrahiert wurde die Zahl 2, Zuweisung an Element
l[1:2]=[5,6] [1,5,6,3] Extrahiert wurde die Liste [2], Zuweisung an Liste
l[1:2]=(5,6) [1,5,6,3] Listen sind austauschbar
l[1:2]="56" [1,'5','6',3] Strings sind Listen!
l[1:1] Leere Liste [], ebenso wie l[1:0]
range([a=0,]b[,s=1]) Liste aus Integer von a bis (ausschließlich) b mit inkrement s
for i in range(1,100,2)
list.append(x) list.extend([x])
list.extend(x) list[len(list):]=x
list.insert(i,x) list[i:i]=[x]
list.remove(x) del list[list.index(x)]
del list[i] list[i:i+1]=[]
del list[i:j] list[i:j]=[] (also: del list[i:i] tut nix!)
pop([i=0]) hole element i und lösche es: pop() LIFO, pop(0) FIFO
list.index(x) index von Element das x enthält, Fehler wenn keins
list.count(x) Anzahl der Elemente die x enthalten
list.sort() Sortieren (verändert list!) (sort fn?)
list.reverse() Liste umdrehen (verändert list!)
filter(fn,list) Liefert Liste der Elemente für die fn() nicht 0 ergibt
map(fn,list[,..]) Transformiert Liste per fn() (jagt alle Elemente durch fn und speichert das Ergebnis)
Mehrere (gleichlange) Listen angebbar für Funktion mit mehreren Argumenten
reduce(fn,l[,start]) x[len(l)] mit x[n]:=fn(l[n-1],x[n-1]) mit x[0]=start bzw. x[0]=l[0]
Funktion wird auf alle Elemente angewendet, wobei das Ergebnis immer wieder reingesteckt wird
Bei assoziativen Funktionen wie Summenbildung bekommt man leicht verständliche Ergebnisse
assoc.iteritems() Itemiterator-Object für Dictionary für "for key,value in assoc..."
enumerate(list) Enumerationsobjekt für "for index,value in enum.."
zip(l1,l2[,lx..]) Liste mit Tupeln für "for v1,v2[,vx..] in zip(..)"
reversed(list) Liste rückwärts
sorted(list) Liste sortiert, wobei die Liste nicht verändert wird
str(ob) Lesbarer Output
repr(ob) Code-Repräsentation so wie es Interpreter wieder schluckt
Auch: Backtick-Operator (aber nimmer verwenden!)
IO
f=open('name', 'r')
f.read([n]) N bytes lesen, wenn nicht da: alles!
f.readline() Zeilenweise
for line in f: Loop über die Zeilen (file ist iterierbar)
f.write(string)
f.seek(n) Relativ zum Anfang (auch: f.seek(n,0))
f.seek(n,1) Relativ zu momentan
f.seek(n,-2) Relativ zum Ende
f.close()
Pickle siehe
docs.python.org/ lib/ module-pickle.html
import pickle
import cPickle Einfachere aber 1000 mal schnellere Variante in Maschinencode
pickle.dump(x,f) Serialisieren
x = pickle.load(f) Deserialisieren
s = pickle.dumps(x) Direkt nach String wandeln
x = pickle.loads(s) Und umgekehrt
- Pickle kann nicht alle Objecte umwandeln, "instanceobject"-Klassen (gebundene Funktionen) gehen nicht (wie auch?).
- Pickle kennt verschiedene Formate, sinnvoll sind eigentlich nur der default (0, Rückwärtskompatibel) und pickle.HIGHEST_PROTOCOL (braucht mindestens dieselbe Python-Version).
- Siehe __getinitargs__ bei Klassen.
Syntax
if expr: [expr] Man kann gleich hinter dem : weiterschreiben
elif expr:
else: Else geht auch für for/while, wird aber bei break übersprungen
while expr:
for a in list Iteriere über Elemente
for k,v in assoc.iteritems(): Iteriere über Key/Value
for i,v in enumerate(list): Iteriere über Index/Value
break / continue wie in C, aber beachte else: das bei break nicht ausgeführt wird
pass NOP
def func(args): *name = unnamed / **name = assoc / benannt und initialisiert
return [wert] Oder letztes Ergebnis der Funktion
func(*l) func(**a) listen bzw. assoziative Arrays (in Python Dictionary genannt) liefern args
lambda args: expr Anonyme Funktion
l = a,b,c "Tupel packing" laut Python, weist erzeugtes Tupel zu
a,b,c = l Übliches Dekompositing einer Liste ("sequence unpacking" laut Python Doc)
[expr for v in list if expr [..]]
Listen-Konstruktor. Expr kann z. B. Tupel etc. sein. Mehrere for/if gehen (verschiedene Vars)
a < b < c a < b and b < c
and / or shortcut-evaluation!
l1 < l2 bei Listen rekursiv und logisch.
string < list Verschiedene Datentypen unlogisch (momentan: Typname wird verglichen)
string.ljust(n) string.rjust(n) string.center(n) string.zfill(n)
letzteres für Zahlen, 0-padding mit Vorzeichenregel (etwas krank!)
try: statement Bei Fehler -> except
except type: type kann Tupel sein für mehrere, oder fehlend bei letzter für catchall
else: Block der ausgeführt wird wenn keine Exception auftrag
finally: Cleanup, wird immer ausgeführt (auch bei break, continue, return)
Ab Python 2.6:
with expr as var: Variable existiert nur innerhalb des "with". Danach wird sie zerstört.
Files werden beim zerstören der Variable geschlossen. With hilft dabei.
Python 2.5:
from __future__ import with_statement
Macht es in python 2.5 verfügbar, "KEYWORD" ist z. B. "with".
Beispiel einer typischen Exception:
class MyError(Exception):
def __init__(self, value):
self.value = value
def __str__(self):
return repr(self.value)
Geklaut bei
docs.python.org/3.0/tutorial/errors.html
Hier ein Beispiel für eine generische Exception:
def test(s):
raise Exception(s)
try:
test("test")
except Exception, p:
print("Exception cought: %s" % repr(p))
With-Decorator
Siehe
www.python.org/dev/peps/pep-0343/
Module
dir() Alle bekannten Module
dir(modul) Inhalt vom Modul
import modul Namen als modul.element ansprechen
from modul import name,..
from modul import * Elemente kann man direkt ansprechen (importiert keine _-Namen)
modul.__doc__ Ist der Doc-String
.py Files werden automatisch in .pyc oder .pyo (-O) übersetzt. -O ist brauchbar -> assert-Statements werden wegoptimiert, bei -OO auch __doc__ (was nix bringt)
Packages
__init__.py Im Verzeichnis, damit der Pfad gefunden wird
from .. import xxx Interne Paketbezüge. Enthält Modul aber __main__ dann so nicht!
__path__ Enthält den Include-Pfad, abändern um Unterpakete anderswo zu finden (besser nicht!)
Klassen
- Python macht immer Pass-By-Reference: Änderungen am Übergabeparameter sieht der Auffrufer! Bei "immutable" Typen (Strings, Zahlen, siehe oben bei Typen) erzeugt man dadurch ein neues Objekt, das somit den Aufrufer nicht erreicht. Das gilt allgemein, nicht nur beim Aufruf einer Funktion oder Methode.
- Member-Funktionen bekommen das Object als ersten Parameter: Konvention ist, das Object "self" zu nennen. Theoretisch aber kann jede Funktion als Member herhalten (zuweisbar).
"def"s sind im folgenden immer innerhalb der Klasse!
class NAME
class NAME(BASE)
class NAME(BASE1,..)
__ATTR__ internal names, reserviert
__ATTR_, __ATTR class private, umgewandelt in __NAME__ATTR bzw. __NAME__ATTR
Nicht von anderen Klassen aus aufrufbar, da NAME immer die aktuelle Klasse ist.
Deshalb auch keine Vererbung dieser Namen.
NAME.__doc__ Üblicher __doc__ string.
NAME.__name__ NAME
NAME.__dict__ Attributs-Collection (genauen Typ muss ich noch rausfinden)
def __init__(self): Initialisierungsfunktion
c=NAME() Erzeugen eines Klassenobjekts (kein "new" notwendig!)
def __init__(self, args):
c=NAME(args) Erzeugen eines Klassenobjekts mit Parametern
c.ATTR = wert Attribut Zuweisen, das geht beliebig (neu, daten, methoden, selbst Base-Klasse)
c.FN() NAME.FN(c) auf
c.FN(args) NAME.FN(c,args)
f = c.FN Ist ATTR eine methode (Funktion) wird automatisch "c" mitgespeichert
f() Implizit NAME.FN(c) (wie komme ich wieder von f auf c? Geht vermutlich irgendwie)
pickle/copy:
def __getinitargs__(self): Aufgrerufen von pickle: __init__ mit gegebenen Tupel beim unpickle aufrufen
Fehlt das, wird __init__ gar nicht aufgerufen!
def __getstate__(self): Pickle verwendet Rückgabe anstelle von __dict__
def __setstate__(self,o): Unpickle setzt so die Werte wieder.
Fehlt __setstate__ muss __getstate__ einen __dict__ typ zurückgeben
c.__class__ Klassenobjekt, für alle Klassenobjekte gleich
__reduce__, __reduce_ex__ Siehe Online-Hilfe zu pickle
__copy__ __deepcopy__ Siehe Online-Hilfe zu copy
Iteratoren und Generatoren
Iteratoren:
Zu iterierende Klasse:
def __iter__(self) Iterator der Klasse abrufen. Liefert ein Iterierbares Objekt. Kann das Objekt selber sein!
iter(x) ist eine Abkürzung für x.__iter__()
Iterator-Objekt:
def next(self): Nächsten Eintrag des Iterators abrufen
Generatoren:
def generator(args):
...
yield wert
...
implizites raise StopIteration am Ende
PEP342 für Python 2.5:
yield yield None
Iterator-Objekt:
def send(self, v): Wert an den letzten yield senden und nächsten yield abrufen
iterator.send(None) ist dasselbe wie iterator.next()
def close(self): Wird beim schließen des Iterators aufgerufen, im Wesentlichen:
self.throw(GeneratorExit)
def throw(self, type, value=None, traceback=None):
yield wird unterbrochen mit: raise type, value, traceback
def __del__(self): Ruft bei der Garbage-Collection self.close() auf.
def generator(args):
...
v=(yield w)
...
try .. catch .. finally wird somit ab Python 2.5 auch in Iteratoren unterstützt. Python 2.4 kann es nicht.
Consumer-Decorator
Siehe
www.python.org/dev/peps/pep-0342/
Library
docs.python.org/lib/
TBD
Weiteres
Dekoratoren:
@classmethod
@staticmethod
Spezielle Dinge:
class.__metaclass__
Siehe
www.ibm.com/developerworks/linux/library/l-pymeta2/
Funktionsaufrufe
apply(function, args) Dasselbe wie function(*args) bzw. function(*args, **kw)
function.__call__(args) Langform von function(args)