Neben der eben eingeführten while-Anweisung kennt Python die bei anderen Sprachen üblichen Kontrollfluß-Anweisungen - mit einigen Tricks.
Die vielleicht bekannteste Anweisung ist die if-Anweisung, z.B.:
>>> # [Code, der 'x' auf irgendeinen Wert setzt...] >>> if x < 0: ... x = 0 ... print 'Negative changed to zero' ... elif x == 0: ... print 'Zero' ... elif x == 1: ... print 'Single' ... else: ... print 'More' ...
Es kann keine oder mehrere elif-Teile geben, und der else-Teil ist optional. Das Schlüsselwort `elif' ist eine Kurzschreibweise für ,,else if`` und ist nützlich, um exzessive Einrückungen zu vermeiden. Eine Sequenz der Art if ... elif ... elif ... ist ein Ersatz für switch- oder case-Anweisungen in anderen Sprachen.
Die for-Anweisung in Python unterscheidet sich ein wenig von dem, was Sie aus C oder Pascal gewohnt sind. Anstatt stets über eine arithmetische Folge von Zahlen zu iterieren (wie in Pascal) oder der Benutzerin die Möglichkeit zu geben, die Schrittweite und Endbedingung der Iteration zu definieren (wie in C), iteriert die for-Anweisung in Python über die Elemente einer Sequenz (z.B. einer Liste oder eines Strings) in der Reihenfolge ihres Auftretens in dieser Sequenz. Beispiel:
>>> # Messe einige Strings: ... a = ['cat', 'window', 'defenestrate'] >>> for x in a: ... print x, len(x) ... cat 3 window 6 defenestrate 12
Es ist nicht sicher, die Sequenz zu modifizieren, über die gerade iteriert wird (das kann nur mit veränderlichen Sequenztypen passieren, z.B. Listen). Wenn Sie die Liste modifizieren müssen, über die Sie iterieren, z.B. um die einzelnen Elemente zu kopieren, müssen Sie über eine Kopie iterieren. Mit der Teilbereichs-Notation ist dies sehr bequem:
>>> for x in a[:]: # Erstelle eine Teilbereichs-Kopie der ganzen Liste. ... if len(x) > 6: a.insert(0, x) ... >>> a ['defenestrate', 'cat', 'window', 'defenestrate']
Falls Sie über eine Sequenz von Zahlen iterieren müssen, kommt die eingebaute Funktion range() sehr gelegen. Sie erzeugt Listen, die arithmetischen Aufzählungen entsprechen, z.B.:
>>> range(10) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
Der angegebene Endpunkt ist nie Teil der erzeugten Liste. range(10) erzeugt eine Liste von 10 Werten, exakt die gültigen Indizes für Elemente einer Sequenz der Länge 10. Es ist möglich, den Bereich bei einer anderen Zahl anfangen zu lassen oder eine andere ganzzahlige Schrittweite anzugeben (sogar negativ):
>>> range(5, 10) [5, 6, 7, 8, 9] >>> range(0, 10, 3) [0, 3, 6, 9] >>> range(-10, -100, -30) [-10, -40, -70]
Um die Indizes einer Sequenz zu durchlaufen, kombiniere man range() und len() wie folgt:
>>> a = ['Mary', 'had', 'a', 'little', 'lamb'] >>> for i in range(len(a)): ... print i, a[i] ... 0 Mary 1 had 2 a 3 little 4 lamb
Die break-Anweisung bricht, wie in C, aus der kleinsten umgebenden for- oder while-Schleife aus.
Die continue-Anweisung, auch aus C geliehen, setzt die Schleife mit der nächsten Iteration fort.
Schleifen-Anweisungen dürfen eine else-Klausel haben. Sie wird ausgeführt, wenn die Schleife vollständig durch die Liste gelaufen ist (mit for) oder wenn die Bedingung falsch wird (mit while), aber nicht, wenn die Schleife durch eine break-Anweisung terminiert wird. Dies wird bei der folgenden Schleife deutlich, die nach Primzahlen sucht:
>>> for n in range(2, 10): ... for x in range(2, n): ... if n % x == 0: ... print n, 'equals', x, '*', n/x ... break ... else: ... print n, 'is a prime number' ... 2 is a prime number 3 is a prime number 4 equals 2 * 2 5 is a prime number 6 equals 2 * 3 7 is a prime number 8 equals 2 * 4 9 equals 3 * 3
Die pass-Anweisung tut nichts. Sie kann benutzt werden, wenn eine Anweisung syntaktisch notwendig ist, ohne daß das Programm wirklich etwas tun muß. Beispiel:
>>> while 1: ... pass # Aktives Warten auf eine Tastatur-Unterbrechung. ...
Wir können eine Funktion schreiben, die die Fibonacci-Folge bis zu einer beliebigen Grenze ausgibt:
>>> def fib(n): # Gib Fibonacci-Reihe bis n aus. ... "Print a Fibonacci series up to n" ... a, b = 0, 1 ... while b < n: ... print b, ... a, b = b, a+b ... >>> # Rufe nun die gerade definierte Funktion auf: ... fib(2000) 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 1597
Das Schlüsselwort def leitet die Definition einer Funktion ein. Ihm muß der Funktionsname folgen sowie eine Liste von formalen Parametern in runden Klammern sowie ein Doppelpunkt. Die Anweisungen, die den Rumpf der Funktion ausmachen, beginnen in der folgenden Zeile, um einen Tabulator eingerückt. Die erste Anweisung des Rumpfes kann optional ein String-Literal sein. Dieses String-Literal ist der Dokumentations-String der Funktion, auch Docstring genannt. Es gibt Werkzeuge, die Docstrings verwenden, um automatisch gedruckte Dokumentation zu erzeugen oder um die Benutzerin interaktiv im Code stöbern zu lassen. Es ist von Vorteil, Docstrings in Ihrem Code zu verwenden. Versuchen Sie, es sich zur Gewohnheit zu machen!
Die Ausführung einer Funktion führt zu einer neuen Symboltabelle mit den lokalen Variablen dieser Funktion. Genauer: alle Variablenzuweisungen in einer Funktion speichern den Wert in der lokalen Symboltabelle, wohingegen Referenzen auf Variablen erst in der lokalen Symboltabelle gesucht werden, dann in der globalen Symboltabelle und dann in der Tabelle der eingebauten Namen. Daher kann in einer Funktion globalen Variablen nicht direkt ein Wert zugewiesen werden (solange sie nicht in in einer global-Anweisung vorkommen), obwohl sie referenziert werden können.
Die eigentlichen Parameter (Argumente) eines Funktionsaufrufs werden dann in die lokale Symboltabelle der aufrufenden Funktion eingefügt, wenn die Funktion aufgerufen wird. Daher werden die Argumente mit Werte-Semantik übergeben (engl. call by value).4.1Wenn eine Funktion eine andere Funktion aufruft, wird eine neue lokale Symboltabelle für diesen Aufruf erzeugt. 4.2
Eine Funktionsdefinition trägt den Namen der Funktion in die aktuelle Symboltabelle ein. Der Wert des Funktionsnamens hat einen Typ, der vom Interpreter als eine benutzerdefinierte Funktion erkannt wird. Dieser Wert kann einem anderen Namen zugewiesen werden, der dann auch als Funktion verwendet werden kann. Dies kann als allgemeiner Mechanismus zur Umbenennung von Funktionen dienen:
>>> fib <function object at 10042ed0> >>> f = fib >>> f(100) 1 1 2 3 5 8 13 21 34 55 89
Sie könnten einwenden, daß fib keine Funktion, sondern eine Prozedur ist. In Python wie in C sind Prozeduren lediglich Funktionen, die keinen Wert zurück geben. Tatsächlich ist es so, technisch gesehen, daß Prozeduren sehr wohl einen Wert zurück geben, wenn auch einen langweiligen. Dieser Wert heißt None (ein eingebauter Name). Die Ausgabe des Wertes None wird normalerweise vom Interpreter unterdrückt, falls es der einzige Ausgabewert ist. Wenn man wirklich will, kann man ihn dennoch sehen:
>>> print fib(0) None
Es ist einfach, eine Funktion zu schreiben, die eine Liste von Zahlen der Fibonacci-Folge zurück gibt, anstatt sie direkt auszudrucken:
>>> def fib2(n): # Gib Fibonacci-Reihe bis n aus. ... "Return a list containing the Fibonacci series up to n" ... result = [] ... a, b = 0, 1 ... while b < n: ... result.append(b) # Siehe unten. ... a, b = b, a+b ... return result ... >>> f100 = fib2(100) # Rufe sie auf. >>> f100 # Gib das Ergebnis aus. [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
Dieses Beispiel demonstriert, wie üblich, einige neue Eigenschaften von Python:
Es ist auch möglich, Funktionen mit einer variablen Anzahl von Argumenten zu definieren. Es gibt drei Formen, die kombiniert werden können:
Die nützlichste Form besteht darin, einen Vorgabewert für ein oder mehrere Argumente zu spezifizieren.
def ask_ok(prompt, retries=4, complaint='Yes or no, please!'): while 1: ok = raw_input(prompt) if ok in ('y', 'ye', 'yes'): return 1 if ok in ('n', 'no', 'nop', 'nope'): return 0 retries = retries - 1 if retries < 0: raise IOError, 'refusenik user' print complaint
Diese Funktion kann entweder so aufgerufen werden: ask_ok('Wollen Sie wirklich beenden?') oder so: ask_ok('Ist es OK, die Datei zu überschreiben?', 2).
Die Vorgabewerte werden im definierenden Geltungsbereich zum Zeitpunkt der Funktionsdefinition ausgewertet. So wird z.B.
i = 5 def f(arg = i): print arg i = 6 f()
den Wert 5 ausgeben.
Wichtiger Hinweis: Ein Vorgabewert wird nur einmal ausgewertet. Das macht dann einen Unterschied, wenn es sich um ein veränderliches Objekt handelt, etwa eine Liste oder ein Dictionary. Die folgende Funktion zum Beispiel sammelt die ihr übergebenen Argumente in aufeinander folgenden Aufrufen:
def f(a, l = []): l.append(a) return l print f(1) print f(2) print f(3)
Das wird folgendes ausgeben:
[1] [1, 2] [1, 2, 3]
Wenn Sie nicht wollen, daß aufeinander folgende Aufrufe sich das veränderliche Objekt teilen, können Sie stattdessen die folgende Funktion verwenden:
def f(a, l = None): if l is None: l = [] l.append(a) return l
Funktionen können auch mit Schlüsselwort-Argumenten in der Form "keyword = value" aufgerufen werden. Diese Funktion zum Beispiel,
def parrot(voltage, state='a stiff', action='voom', type='Norwegian Blue'): print "-- This parrot wouldn't", action, print "if you put", voltage, "Volts through it." print "-- Lovely plumage, the", type print "-- It's", state, "!"
könnte in allen folgenden Varianten aufgerufen werden:
parrot(1000) parrot(action = 'VOOOOOM', voltage = 1000000) parrot('a thousand', state = 'pushing up the daisies') parrot('a million', 'bereft of life', 'jump')
aber diese Aufrufe wären alle ungültig:
parrot() # Notwendiges Argument fehlt. parrot(voltage=5.0, 'dead') # Schluesselwort-Argument folgt Schluesselwort. parrot(110, voltage=220) # Doppelter Wert fuer ein Argument. parrot(actor='John Cleese') # Unbekanntes Schluesselwort.
Allgemein gilt, daß Positions-Argumente vor Schlüssel-Argumenten in einer Argumentliste stehen müssen, wobei die Schlüssel aus den formalen Parameternamen gewählt werden müssen. Es ist unwichtig, ob ein formaler Parameter einen Vorgabewert hat oder nicht. Keinem Argument darf ein Wert mehr als einmal zugewiesen werden - Namen von formalen Parametern, die mit Positions-Argumenten korrespondieren, können nicht als Schlüssel im gleichen Aufruf verwendet werden.
Wenn ein letzter formaler Parameter der Form **name existiert, so wird ihm ein Dictionary zugewiesen, der alle Schlüssel-Argumente enthält, deren Schlüssel nicht mit einem formalen Parameter korrespondiert. Das darf kombiniert werden mit einem formalen Parameter der Form *name (beschrieben im nächsten Unterabschnitt), der ein Tupel mit den Positions-Argumenten zugewiesen bekommt, die zusätzlich zu denen der formalen Parameterliste existieren. (*name muß vor **name stehen.) Wenn wir z.B. die folgende Funktion definieren:
def cheeseshop(kind, *arguments, **keywords): print "-- Do you have any", kind, '?' print "-- I'm sorry, we're all out of", kind for arg in arguments: print arg print '-'*40 for kw in keywords.keys(): print kw, ':', keywords[kw]
könnte sie wie folgt aufgerufen werden:
cheeseshop('Limburger', "It's very runny, sir.", "It's really very, VERY runny, sir.", client='John Cleese', shopkeeper='Michael Palin', sketch='Cheese Shop Sketch')
und natürlich bestünde die Ausgabe in:
-- Do you have any Limburger ? -- I'm sorry, we're all out of Limburger It's very runny, sir. It's really very, VERY runny, sir. ---------------------------------------- client : John Cleese shopkeeper : Michael Palin sketch : Cheese Shop Sketch
Schließlich besteht die am wenigsten benutzte Möglichkeit darin, daß eine Funktion mit einer beliebigen Anzahl von Argumenten aufgerufen werden kann. Diese Argumente werden in einem Tupel zusammengefaßt. Vor der variablen Anzahl von Argumenten können beliebig viele normale Argumente stehen (auch keine).
def fprintf(file, format, *args): file.write(format % args)
Wegen der großen Nachfrage wurden einige der üblichen Eigenschaften von funktionalen Programmiersprachen in Python aufgenommen. Mit dem lambda-Schlüsselwort können kleine, anonyme Funktionen erzeugt werden. Dies ist eine Funktion, die die Summe zweier Argumente zurück gibt: "lambda a, b: a+b". Lambda-Formen können verwendet werden, wann immer Funktions-Objekte benötigt werden. Syntaktisch sind sie beschränkt auf einen einzigen Ausdruck. Semantisch sind sie nichts als ein syntaktisches Zuckerl für eine normale Funktionsdefinition. Wie bei verschachtelten Funktionsdefinitionen können lambda-Formen keine Variablen des äußeren Geltungsbereichs referenzieren, aber das kann durch vernünftige Verwendung von Argumenten mit Vorgabewerten umgangen werden, z.B.:
def make_incrementor(n): return lambda x, incr=n: x+incr
Allmählich formieren sich Konventionen über den Inhalt und das Format von Dokumentations-Strings.
Die erste Zeile sollte immer eine sehr knappe Zusammenfassung der Aufgabe des Objektes sein. Um es kurz zu machen, sollte sie nicht explizit den Namen oder Typ des Objektes enthalten, da diese mit anderen Mitteln zur Verfügung stehen (außer, wenn der Name ein Verb ist, das die Operation einer Funktion beschreibt). Diese Zeile sollte mit einem Großbuchstaben beginnen und mit einem Punkt enden.
Falls der Docstring noch mehr Zeilen enthält, sollte die zweite Zeile leer sein, um eine sichtbare Trennung von Zusammenfassung und Rest der Beschreibung vorzunehmen. Die folgenden Zeilen sollten ein oder mehrere Absätze sein, die Aufrufkonventionen, Seiteneffekte, etc. des Objektes beschreiben.
Der Python-Parser belässt die Einrückung von mehrzeiligen String-Literalen, d.h. daß Dokumentations-Werkzeuge diese Einrückung selbst entfernen müssen. Dies kann mit den folgenden Konventionen geschehen: Die erste nicht-leere Zeile nach der ersten Zeile des Strings bestimmt das Maß der Einrückung für den gesamten Docstring. (Wir können die erste Zeile nicht auswerten, da sie normalerweise direkt nach den - eingerückten - öffnenden Anführungszeichen kommt, so daß ihre Einrückung im String-Literal nicht ersichtlich ist.) Leerzeichen, die ,,äquivalent`` zu dieser Einrückung sind, werden dann vom linken Rand aller Zeilen entfernt. Zeilen, die weniger eingerückt sind, sollten nicht vorkommen, aber wenn doch, sollte der gesamte linke Leerraum entfernt werden. Der Test auf Leerraum sollte nach Expansion von Tabulatoren (meist auf acht Zeichen) erfolgen.