FAQ zu Bibliothek und Erweiterungen¶
Allgemeine Fragen zur Bibliothek¶
Wie finde ich ein Modul oder eine Anwendung für Aufgabe X?¶
Sieh in der Bibliotheksreferenz nach, ob es ein passendes Modul der Standardbibliothek gibt. (Irgendwann weißt du, was in der Standardbibliothek steckt, und kannst diesen Schritt überspringen.)
Für Pakete von Dritten suche im Python Package Index oder versuche es mit Google oder einer anderen Suchmaschine. Nach „Python“ plus einem oder zwei Stichwörtern zu deinem Thema zu suchen findet meist etwas Hilfreiches.
Wo ist die Quelldatei math.py (socket.py, regex.py und so weiter)?¶
Findest du für ein Modul keine Quelldatei, ist es vielleicht ein integriertes oder dynamisch geladenes Modul, das in C, C++ oder einer anderen kompilierten Sprache umgesetzt ist. In diesem Fall hast du die Quelldatei möglicherweise nicht, oder sie heißt etwa mathmodule.c und liegt irgendwo in einem C-Quellverzeichnis und nicht im Python-Pfad.
Es gibt (mindestens) drei Arten von Modulen in Python:
Module, die in Python geschrieben sind (.py);
Module, die in C geschrieben und dynamisch geladen werden (.dll, .pyd, .so, .sl und so weiter);
Module, die in C geschrieben und mit dem Interpreter gebunden sind. Um eine Liste davon zu bekommen, gib ein:
import sys print(sys.builtin_module_names)
Wie mache ich ein Python-Skript unter Unix ausführbar?¶
Du musst zwei Dinge tun: Der Modus der Skriptdatei muss ausführbar sein, und die erste Zeile muss mit #! beginnen, gefolgt vom Pfad des Python-Interpreters.
Das Erste erledigst du mit chmod +x scriptfile oder vielleicht chmod 755 scriptfile.
Das Zweite geht auf mehrere Weisen. Am geradlinigsten ist es,
#!/usr/local/bin/python
als allererste Zeile deiner Datei zu schreiben, mit dem Pfadnamen, unter dem der Python-Interpreter auf deiner Plattform installiert ist.
Soll das Skript unabhängig davon sein, wo der Python-Interpreter liegt, kannst du das Programm env verwenden. Fast alle Unix-Varianten unterstützen das Folgende, sofern der Python-Interpreter in einem Verzeichnis im PATH des Benutzers liegt:
#!/usr/bin/env python
Mach das nicht bei CGI-Skripten. Die Variable PATH ist für CGI-Skripte oft sehr knapp gehalten, du musst deshalb den tatsächlichen absoluten Pfadnamen des Interpreters verwenden.
Gelegentlich ist die Umgebung eines Benutzers so voll, dass das Programm /usr/bin/env scheitert, oder es gibt überhaupt kein env-Programm. In diesem Fall kannst du den folgenden Trick versuchen (von Alex Rezinsky):
#! /bin/sh
""":"
exec python $0 ${1+"$@"}
"""
Der kleine Nachteil ist, dass dies die __doc__-Zeichenkette des Skripts festlegt. Das kannst du aber beheben, indem du
__doc__ = """...Whatever..."""
Gibt es ein curses/termcap-Paket für Python?¶
Für Unix-Varianten: Die Standard-Quellcode-Distribution von Python bringt im Unterverzeichnis Modules ein curses-Modul mit, das allerdings nicht standardmäßig kompiliert wird. (Beachte, dass es in der Windows-Distribution nicht verfügbar ist – es gibt kein curses-Modul für Windows.)
Das Modul curses unterstützt die grundlegenden curses-Funktionen sowie viele zusätzliche Funktionen aus ncurses und SYSV-curses, etwa Farben, alternative Zeichensätze, Pads und Mausunterstützung. Das bedeutet, dass das Modul mit Betriebssystemen nicht kompatibel ist, die nur BSD-curses haben, aber es scheint derzeit keine gepflegten Betriebssysteme zu geben, die in diese Kategorie fallen.
Gibt es in Python eine Entsprechung zu onexit() aus C?¶
Das Modul atexit stellt eine Funktion register bereit, die onexit() aus C ähnelt.
Warum funktionieren meine Signalbehandler nicht?¶
Das häufigste Problem ist, dass der Signalbehandler mit der falschen Argumentliste deklariert ist. Er wird so aufgerufen:
handler(signum, frame)
er sollte also mit zwei Parametern deklariert werden:
def handler(signum, frame):
...
Häufige Aufgaben¶
Wie teste ich ein Python-Programm oder einen Bestandteil davon?¶
Python bringt zwei Testframeworks mit. Das Modul doctest findet Beispiele in den Docstrings eines Moduls und führt sie aus, wobei es die Ausgabe mit der im Docstring angegebenen erwarteten Ausgabe vergleicht.
Das Modul unittest ist ein aufwendigeres Testframework, nachempfunden den Testframeworks von Java und Smalltalk.
Um das Testen zu erleichtern, solltest du in deinem Programm einen guten modularen Entwurf verwenden. Dein Programm sollte fast alle Funktionalität in Funktionen oder Klassenmethoden kapseln – und das hat manchmal den überraschenden und erfreulichen Effekt, dass das Programm schneller läuft, weil Zugriffe auf lokale Variablen schneller sind als auf globale. Außerdem sollte das Programm es vermeiden, von veränderten globalen Variablen abzuhängen, denn das macht das Testen viel schwieriger.
Die „globale Hauptlogik“ deines Programms darf so einfach sein wie
if __name__ == "__main__":
main_logic()
am Ende des Hauptmoduls deines Programms.
Sobald dein Programm als überschaubare Sammlung von Funktions- und Klassenverhalten organisiert ist, solltest du Testfunktionen schreiben, die diese Verhalten durchlaufen. Jedem Modul lässt sich eine Testsammlung zuordnen, die eine Folge von Tests automatisiert. Das klingt nach viel Arbeit, ist aber überraschend leicht, weil Python so knapp und flexibel ist. Du kannst das Programmieren viel angenehmer und unterhaltsamer machen, indem du deine Testfunktionen parallel zum „produktiven Code“ schreibst, denn so lassen sich Fehler und sogar Entwurfsschwächen früher finden.
„Hilfsmodule“, die nicht als Hauptmodul eines Programms gedacht sind, dürfen einen Selbsttest des Moduls enthalten.
if __name__ == "__main__":
self_test()
Selbst Programme, die mit komplexen externen Schnittstellen arbeiten, lassen sich testen, wenn die externen Schnittstellen nicht verfügbar sind, indem man „falsche“ Schnittstellen verwendet, die in Python umgesetzt sind.
Wie erzeuge ich aus Docstrings Dokumentation?¶
Das Modul pydoc kann aus den Docstrings in deinem Python-Quellcode HTML erzeugen. Eine Alternative, um API-Dokumentation ausschließlich aus Docstrings zu erzeugen, ist epydoc. Auch Sphinx kann Inhalte aus Docstrings einbeziehen.
Wie bekomme ich einzelne Tastendrücke?¶
Für Unix-Varianten gibt es mehrere Lösungen. Mit curses geht das geradeheraus, aber curses ist ein recht umfangreiches Modul, in das man sich einarbeiten muss.
Threads¶
Wie programmiere ich mit Threads?¶
Verwende unbedingt das Modul threading und nicht das Modul _thread. Das Modul threading baut bequeme Abstraktionen auf den grundlegenden Mitteln auf, die das Modul _thread bereitstellt.
Keiner meiner Threads scheint zu laufen. Warum?¶
Sobald der Haupt-Thread sich beendet, werden alle Threads getötet. Dein Haupt-Thread läuft zu schnell durch und gibt den Threads keine Zeit, irgendetwas zu tun.
Eine einfache Abhilfe ist, am Ende des Programms eine Wartezeit einzufügen, die lang genug ist, damit alle Threads fertig werden:
import threading, time
def thread_task(name, n):
for i in range(n):
print(name, i)
for i in range(10):
T = threading.Thread(target=thread_task, args=(str(i), i))
T.start()
time.sleep(10) # <---------------------------!
Aber jetzt laufen die Threads (auf vielen Plattformen) nicht parallel, sondern scheinen hintereinander zu laufen, einer nach dem anderen! Der Grund ist, dass der Thread-Planer des Betriebssystems keinen neuen Thread startet, solange der vorherige nicht blockiert ist.
Eine einfache Abhilfe ist, am Anfang der Ausführungsfunktion eine winzige Wartezeit einzufügen:
def thread_task(name, n):
time.sleep(0.001) # <--------------------!
for i in range(n):
print(name, i)
for i in range(10):
T = threading.Thread(target=thread_task, args=(str(i), i))
T.start()
time.sleep(10)
Statt zu versuchen, einen guten Wert für die Wartezeit von time.sleep() zu erraten, ist es besser, irgendeine Art von Semaphor-Mechanismus zu verwenden. Eine Idee ist, mit dem Modul queue ein Warteschlangenobjekt zu erzeugen, jeden Thread beim Beenden ein Zeichen an die Warteschlange anhängen zu lassen und den Haupt-Thread so viele Zeichen aus der Warteschlange zu lesen, wie es Threads gibt.
Wie verteile ich Arbeit auf eine Reihe von Arbeiter-Threads?¶
Am einfachsten geht das mit dem Modul concurrent.futures, insbesondere mit der Klasse ThreadPoolExecutor.
Oder du schreibst deine eigene Logik von Hand, wenn du die Verteilung genau steuern willst. Erzeuge mit dem Modul queue eine Warteschlange, die eine Liste von Aufträgen enthält. Die Klasse Queue führt eine Liste von Objekten und hat eine Methode .put(obj), die Elemente zur Warteschlange hinzufügt, sowie eine Methode .get(), die sie zurückgibt. Die Klasse kümmert sich um die nötige Sperrung, damit jeder Auftrag genau einmal ausgegeben wird.
Hier ein einfaches Beispiel:
import threading, queue, time
# Der Arbeiter-Thread holt Aufträge aus der Warteschlange. Ist sie leer,
# nimmt er an, dass keine Arbeit mehr kommt, und beendet sich.
# (In der Praxis laufen Arbeiter, bis sie beendet werden.)
def worker():
print('Running worker')
time.sleep(0.1)
while True:
try:
arg = q.get(block=False)
except queue.Empty:
print('Worker', threading.current_thread(), end=' ')
print('queue empty')
break
else:
print('Worker', threading.current_thread(), end=' ')
print('running with argument', arg)
time.sleep(0.5)
# Warteschlange erzeugen
q = queue.Queue()
# einen Vorrat von 5 Arbeitern starten
for i in range(5):
t = threading.Thread(target=worker, name='worker %i' % (i+1))
t.start()
# beginnen, Arbeit in die Warteschlange zu legen
for i in range(50):
q.put(i)
# den Threads Zeit zum Laufen geben
print('Main thread sleeping')
time.sleep(5)
Ausgeführt ergibt das die folgende Ausgabe:
Running worker
Running worker
Running worker
Running worker
Running worker
Main thread sleeping
Worker <Thread(worker 1, started 130283832797456)> running with argument 0
Worker <Thread(worker 2, started 130283824404752)> running with argument 1
Worker <Thread(worker 3, started 130283816012048)> running with argument 2
Worker <Thread(worker 4, started 130283807619344)> running with argument 3
Worker <Thread(worker 5, started 130283799226640)> running with argument 4
Worker <Thread(worker 1, started 130283832797456)> running with argument 5
...
Weitere Einzelheiten stehen in der Dokumentation des Moduls. Die Klasse Queue bietet eine reichhaltige Schnittstelle.
Welche Arten der Änderung globaler Werte sind thread-sicher?¶
Intern wird ein global interpreter lock (GIL) verwendet, um sicherzustellen, dass immer nur ein Thread in der Python-VM läuft. Im Allgemeinen wechselt Python nur zwischen Bytecode-Anweisungen den Thread. Wie häufig es wechselt, lässt sich über sys.setswitchinterval() einstellen. Jede Bytecode-Anweisung und damit aller von ihr erreichte C-Code ist aus Sicht eines Python-Programms deshalb atomar.
Theoretisch bedeutet das, dass eine genaue Abrechnung ein genaues Verständnis der Bytecode-Umsetzung der PVM erfordert. In der Praxis bedeutet es, dass Operationen auf gemeinsam genutzten Variablen integrierter Datentypen (ints, Listen, Dictionarys und so weiter), die „atomar aussehen“, es wirklich sind.
Zum Beispiel sind die folgenden Operationen alle atomar (L, L1, L2 sind Listen, D, D1, D2 sind Dictionarys, x, y sind Objekte, i, j sind ints):
L.append(x)
L1.extend(L2)
x = L[i]
x = L.pop()
L1[i:j] = L2
L.sort()
x = y
x.field = y
D[x] = y
D1.update(D2)
D.keys()
Diese nicht:
i = i+1
L.append(L[-1])
L[i] = L[j]
D[x] = D[x] + 1
Operationen, die andere Objekte ersetzen, können die Methode __del__() dieser anderen Objekte auslösen, sobald deren Referenzzähler null erreicht, und das kann sich auswirken. Besonders gilt das für Massenaktualisierungen von Dictionarys und Listen. Im Zweifel: nimm einen Mutex!
Können wir den Global Interpreter Lock nicht loswerden?¶
Der global interpreter lock (GIL) wird oft als Hindernis für den Einsatz von Python auf hochwertigen Mehrprozessor-Servern gesehen, denn ein Python-Programm mit mehreren Threads nutzt tatsächlich nur eine CPU, weil (fast) aller Python-Code nur laufen darf, solange der GIL gehalten wird.
Mit der Zustimmung zu PEP 703 ist nun die Arbeit daran im Gange, den GIL aus der CPython-Implementierung von Python zu entfernen. Zunächst wird das als optionaler Compiler-Schalter beim Bauen des Interpreters umgesetzt, sodass getrennte Builds mit und ohne GIL verfügbar sein werden. Langfristig besteht die Hoffnung, sich auf einen einzigen Build festzulegen, sobald die Auswirkungen des Entfernens auf die Geschwindigkeit vollständig verstanden sind. Python 3.13 wird wahrscheinlich die erste Veröffentlichung sein, die diese Arbeit enthält, auch wenn sie darin vielleicht noch nicht vollständig funktioniert.
Die aktuelle Arbeit am Entfernen des GIL beruht auf einem Fork von Python 3.9 ohne GIL von Sam Gross. Davor, zu Zeiten von Python 1.5, hat Greg Stein tatsächlich einen umfassenden Satz von Patches umgesetzt (die „free threading“-Patches), die den GIL entfernten und durch feingranulare Sperren ersetzten. Adam Olsen hat in seinem Projekt python-safethread ein ähnliches Experiment gemacht. Leider zeigten beide früheren Experimente einen scharfen Einbruch der Geschwindigkeit bei einzelnen Threads, mindestens 30 % langsamer, wegen der Menge an feingranularen Sperren, die zum Ausgleich für das entfernte GIL nötig waren. Der Fork von Python 3.9 ist der erste Versuch, den GIL mit annehmbaren Auswirkungen auf die Geschwindigkeit zu entfernen.
Dass der GIL in den aktuellen Python-Veröffentlichungen vorhanden ist, bedeutet nicht, dass du Python auf Maschinen mit mehreren CPUs nicht gut nutzen kannst! Du musst nur kreativ dabei sein, die Arbeit auf mehrere Prozesse statt auf mehrere Threads zu verteilen. Die Klasse ProcessPoolExecutor im neuen Modul concurrent.futures bietet dafür einen einfachen Weg. Das Modul multiprocessing bietet eine API auf niedrigerer Ebene, falls du die Verteilung der Aufgaben genauer steuern willst.
Der umsichtige Einsatz von C-Erweiterungen hilft ebenfalls. Verwendest du eine C-Erweiterung für eine zeitaufwendige Aufgabe, kann die Erweiterung den GIL freigeben, während der Ausführungsfaden im C-Code ist, und anderen Threads so erlauben, etwas Arbeit zu erledigen. Einige Module der Standardbibliothek wie zlib und hashlib machen das bereits.
Ein anderer Weg, die Auswirkung des GIL zu verringern, ist, ihn zu einer Sperre pro Interpreter-Zustand zu machen statt zu einer wirklich globalen. Das wurde erstmals in Python 3.12 umgesetzt und ist in der C-API verfügbar. Eine Python-Schnittstelle dazu wird für Python 3.13 erwartet. Die wichtigste Einschränkung dürfte derzeit bei Erweiterungsmodulen von Dritten liegen, denn diese müssen mit mehreren Interpretern im Blick geschrieben sein, um nutzbar zu sein, weshalb viele älteren Erweiterungsmodule nicht nutzbar sein werden.
Ein- und Ausgabe¶
Wie lösche ich eine Datei? (Und andere Fragen zu Dateien …)¶
Verwende os.remove(filename) oder os.unlink(filename). Die Dokumentation dazu steht beim Modul os. Die beiden Funktionen sind identisch, unlink() ist einfach der Name des Unix-Systemaufrufs für diese Funktion.
Um ein Verzeichnis zu entfernen, verwende os.rmdir(), zum Anlegen os.mkdir(). os.makedirs(path) legt alle Zwischenverzeichnisse in path an, die noch nicht vorhanden sind. os.removedirs(path) entfernt Zwischenverzeichnisse, solange sie leer sind. Willst du einen ganzen Verzeichnisbaum samt Inhalt löschen, verwende shutil.rmtree().
Um eine Datei umzubenennen, verwende os.rename(old_path, new_path).
Um eine Datei abzuschneiden, öffne sie mit f = open(filename, "rb+") und verwende f.truncate(offset). Voreingestellt ist offset die aktuelle Position des Lesezeigers. Für Dateien, die mit os.open() geöffnet wurden, gibt es außerdem os.ftruncate(fd, offset), wobei fd der Dateideskriptor ist, also eine kleine ganze Zahl.
Das Modul shutil enthält außerdem eine Reihe von Funktionen für die Arbeit mit Dateien, darunter copyfile(), copytree() und rmtree().
Wie kopiere ich eine Datei?¶
Das Modul shutil enthält eine Funktion copyfile(). Beachte, dass sie auf NTFS-Datenträgern unter Windows keine alternativen Datenströme kopiert und auf HFS+-Datenträgern unter macOS keine Ressourcenzweige, auch wenn beides inzwischen selten verwendet wird. Sie kopiert außerdem keine Dateirechte und Metadaten, wobei shutil.copy2() davon das meiste erhält, wenn auch nicht alles.
Wie lese oder schreibe ich Binärdaten?¶
Um komplexe Binärdatenformate zu lesen oder zu schreiben, verwendest du am besten das Modul struct. Es erlaubt dir, eine Zeichenkette mit Binärdaten zu nehmen, meist Zahlen, und sie in Python-Objekte umzuwandeln — und umgekehrt.
Der folgende Code liest zum Beispiel zwei 2-Byte-Ganzzahlen und eine 4-Byte-Ganzzahl im Big-Endian-Format aus einer Datei:
import struct
with open(filename, "rb") as f:
s = f.read(8)
x, y, z = struct.unpack(">hhl", s)
Das ‚>‘ in der Formatzeichenkette erzwingt Big-Endian-Daten. Der Buchstabe ‚h‘ liest eine „short integer“ (2 Byte) und ‚l‘ eine „long integer“ (4 Byte) aus der Zeichenkette.
Für gleichmäßigere Daten, etwa eine Liste aus durchweg ints oder floats, kannst du auch das Modul array verwenden.
Ich kann os.read() offenbar nicht auf einer mit os.popen() erzeugten Pipe verwenden. Warum?¶
os.read() ist eine Funktion auf niedriger Ebene, die einen Dateideskriptor nimmt, also eine kleine ganze Zahl, die die geöffnete Datei darstellt. os.popen() erzeugt ein Dateiobjekt auf höherer Ebene, denselben Typ, den die integrierte Funktion open() zurückgibt. Um also n Byte aus einer mit os.popen() erzeugten Pipe p zu lesen, musst du p.read(n) verwenden.
Wie greife ich auf die serielle Schnittstelle (RS232) zu?¶
Für Win32, OSX, Linux, BSD, Jython, IronPython:
Für Unix siehe einen Usenet-Beitrag von Mitch Chapman:
Warum schließt das Schließen von sys.stdout (stdin, stderr) es nicht wirklich?¶
Dateiobjekte in Python sind eine Abstraktionsschicht auf höherer Ebene über den C-Dateideskriptoren auf niedriger Ebene.
Für die meisten Dateiobjekte, die du in Python über die integrierte Funktion open() erzeugst, kennzeichnet f.close() das Python-Dateiobjekt aus Sicht von Python als geschlossen und sorgt außerdem dafür, dass der darunter liegende C-Dateideskriptor geschlossen wird. Das passiert auch automatisch im Destruktor von f, wenn f zu Müll wird.
Aber stdin, stdout und stderr werden von Python besonders behandelt, weil C ihnen ebenfalls einen besonderen Status gibt. sys.stdout.close() auszuführen kennzeichnet das Dateiobjekt auf Python-Ebene als geschlossen, schließt den zugehörigen C-Dateideskriptor aber nicht.
Um den darunter liegenden C-Dateideskriptor für einen dieser drei zu schließen, solltest du zuerst sicher sein, dass du das wirklich willst — du bringst damit zum Beispiel vielleicht Erweiterungsmodule in Schwierigkeiten, die Ein- und Ausgabe machen wollen. Wenn ja, verwende os.close():
os.close(stdin.fileno())
os.close(stdout.fileno())
os.close(stderr.fileno())
Oder du verwendest die Zahlenkonstanten 0, 1 und 2.
Netzwerk- und Internetprogrammierung¶
Welche WWW-Werkzeuge gibt es für Python?¶
Siehe die Kapitel Internet Protocols and Support und Verarbeitung von Internetdaten im Referenzhandbuch der Bibliothek. Python hat viele Module, die dir beim Bau von Websystemen auf Server- und auf Clientseite helfen.
Eine Übersicht der verfügbaren Frameworks pflegt Paul Boddie unter https://wiki.python.org/moin/WebProgramming.
Welches Modul sollte ich zur Hilfe beim Erzeugen von HTML verwenden?¶
Eine Sammlung nützlicher Links findest du auf der Wiki-Seite Web Programming.
Wie versende ich aus einem Python-Skript E-Mail?¶
Verwende das Modul smtplib aus der Standardbibliothek.
Hier ein sehr einfacher interaktiver Mailversender, der es verwendet. Diese Methode funktioniert auf jedem Rechner, der einen SMTP-Dienst unterstützt.
import sys, smtplib
fromaddr = input("From: ")
toaddrs = input("To: ").split(',')
print("Enter message, end with ^D:")
msg = ''
while True:
line = sys.stdin.readline()
if not line:
break
msg += line
# der eigentliche Mailversand
server = smtplib.SMTP('localhost')
server.sendmail(fromaddr, toaddrs, msg)
server.quit()
Eine Alternative nur für Unix verwendet sendmail. Der Ort des Programms sendmail unterscheidet sich je nach System, manchmal ist es /usr/lib/sendmail, manchmal /usr/sbin/sendmail. Die Manpage von sendmail hilft dir weiter. Hier etwas Beispielcode:
import os
SENDMAIL = "/usr/sbin/sendmail" # Ort von sendmail
p = os.popen("%s -t -i" % SENDMAIL, "w")
p.write("To: receiver@example.com\n")
p.write("Subject: test\n")
p.write("\n") # Leerzeile, die Kopfzeilen vom Rumpf trennt
p.write("Some text\n")
p.write("some more text\n")
sts = p.close()
if sts != 0:
print("Sendmail exit status", sts)
Wie vermeide ich Blockieren in der Methode connect() eines Sockets?¶
Das Modul select wird häufig verwendet, um bei asynchroner Ein- und Ausgabe auf Sockets zu helfen.
Damit das TCP-connect nicht blockiert, kannst du den Socket in den nicht blockierenden Modus setzen. Beim connect() verbindest du dich dann entweder sofort (unwahrscheinlich) oder bekommst eine Ausnahme, die die Fehlernummer als .errno enthält. errno.EINPROGRESS zeigt an, dass die Verbindung im Aufbau, aber noch nicht fertig ist. Verschiedene Betriebssysteme geben verschiedene Werte zurück, du musst also prüfen, was auf deinem System zurückkommt.
Mit der Methode connect_ex() kannst du vermeiden, dass eine Ausnahme entsteht. Sie gibt einfach den errno-Wert zurück. Zum Abfragen kannst du connect_ex() später erneut aufrufen – 0 oder errno.EISCONN zeigen an, dass du verbunden bist – oder du übergibst diesen Socket an select.select(), um zu prüfen, ob er beschreibbar ist.
Datenbanken¶
Gibt es in Python Schnittstellen zu Datenbankpaketen?¶
Ja.
Schnittstellen zu plattenbasierten Hashes wie DBM und GDBM sind ebenfalls im Standard-Python enthalten. Es gibt außerdem das Modul sqlite3, das eine leichtgewichtige, plattenbasierte relationale Datenbank bereitstellt.
Unterstützung für die meisten relationalen Datenbanken ist verfügbar. Einzelheiten stehen auf der Wiki-Seite DatabaseProgramming.
Wie setzt man in Python persistente Objekte um?¶
Das Bibliotheksmodul pickle löst das auf sehr allgemeine Weise, auch wenn du Dinge wie offene Dateien, Sockets oder Fenster weiterhin nicht speichern kannst, und das Bibliotheksmodul shelve verwendet pickle und (g)dbm, um persistente Mappings zu erzeugen, die beliebige Python-Objekte enthalten.
Mathematik und Numerik¶
Wie erzeuge ich in Python Zufallszahlen?¶
Das Standardmodul random setzt einen Zufallszahlengenerator um. Die Verwendung ist einfach:
import random
random.random()
Das gibt eine zufällige Gleitkommazahl im Bereich [0, 1) zurück.
In diesem Modul gibt es auch viele weitere spezialisierte Generatoren, zum Beispiel:
randrange(a, b)wählt eine ganze Zahl im Bereich [a, b).uniform(a, b)wählt eine Gleitkommazahl im Bereich [a, b).normalvariate(mean, sdev)zieht aus der Normalverteilung, also der Gauß-Verteilung.
Einige Funktionen auf höherer Ebene arbeiten direkt auf Sequenzen, zum Beispiel:
choice(S)wählt ein zufälliges Element aus einer gegebenen Sequenz.shuffle(L)mischt eine Liste an ihrem Platz, permutiert sie also zufällig.
Es gibt außerdem eine Klasse Random, die du instanziieren kannst, um mehrere voneinander unabhängige Zufallszahlengeneratoren zu erzeugen.