PDF-Version - freiesMagazin
PDF-Version - freiesMagazin
PDF-Version - freiesMagazin
Sie wollen auch ein ePaper? Erhöhen Sie die Reichweite Ihrer Titel.
YUMPU macht aus Druck-PDFs automatisch weboptimierte ePaper, die Google liebt.
weshalb es auch an diesem Beispiel erörtert werden<br />
soll. Für gewöhnlich wird beim Umgang mit<br />
Dateien ein Konstrukt wie das folgende benötigt:<br />
1 handler = open("datei.txt", "r")<br />
2 try:<br />
3 print handler.read()<br />
4 finally:<br />
5 handler.close()<br />
In Zeile 1 wird dabei eine Datei geöffnet und das<br />
daraus resultierende Datei-Objekt an den Namen<br />
handler gebunden. In Zeile 3 wird der Inhalt der<br />
Datei ausgegeben. Der try...finally-Block<br />
stellt sicher, dass das Datei-Objekt anschließend<br />
in jedem Fall geschlossen wird – auch wenn beim<br />
Auslesen der Datei in Zeile 3 eventuell Fehler<br />
aufgetreten sind. Die Konstruktion „Vorbereiten,<br />
Bearbeiten, Aufräumen“ ist allerdings auch in anderen<br />
Zusammenhängen so häufig anzutreffen,<br />
dass ab Python 2.5 mit with eine deutliche Vereinfachung<br />
für derartige Fälle eingeführt wurde:<br />
1 with open("datei.txt", "r") as <br />
handler:<br />
2 print handler.read()<br />
Auch hier wird zunächst die Datei open.txt<br />
zum Lesen geöffnet und das daraus resultierende<br />
Datei-Objekt an den Namen handler gebunden.<br />
Allerdings erfolgt die Zuweisung des Namens<br />
hier durch das Schlüsselwort as. In Zeile 2<br />
wird – wie gehabt – der Inhalt der Datei ausgegeben.<br />
Damit sind die beiden Schritte „Vorbereiten“<br />
und „Bearbeiten“ abgehandelt. Das Aufräumen<br />
erfolgt mit dem Verlassen der Kontrollstruktur, al-<br />
so am Ende des with-Blocks. Es muss nicht explizit<br />
durchgeführt werden. Wie funktioniert das?<br />
Seit Python 2.5 gibt es zwei neue spezielle<br />
Methoden, die Objekte implementieren können:<br />
__enter__ und __exit__. Die Methode<br />
__enter__ ist für die Vorbereitung zuständig und<br />
wird implizit beim Betreten des with-Blocks aufgerufen.<br />
Der Rückgabewert dieser Methode wird<br />
dann an den mit as angegebenen Namen gebunden<br />
– oben also an den Namen handler. Die Methode<br />
__exit__ wird beim Verlassen des with-<br />
Blocks aufgerufen – unabhängig davon, ob ein<br />
Fehler aufgetreten ist oder nicht.<br />
Diese Konstruktion wird im Folgenden auch<br />
für die Datenbank verwendet. Da die SQLite-<br />
Schnittstelle für Python von Haus aus noch keinen<br />
Gebrauch von diesem neuen Sprachmittel<br />
macht, wird es hier selbst implementiert.<br />
Der Cursor<br />
SQLite kennt sogenannte Cursor, mit denen Datensätze<br />
in Datenbanken ausgelesen und bearbeitet<br />
werden [10]. In der Regel folgt auch das<br />
Arbeiten mit Cursorn dem Schema „Vorbereiten,<br />
Bearbeiten, Aufräumen“, weshalb sich hier die<br />
Verwendung der with-Anweisung empfiehlt.<br />
Das bisherige Skript aus dem letzten Teil wird<br />
nun um diese Klasse ergänzt:<br />
class Cursor(object):<br />
def __init__(self , connection):<br />
self.connection = connection<br />
def __enter__(self):<br />
self.cursor = self.connection.cursor()<br />
return self.cursor<br />
PROGRAMMIERUNG<br />
def __exit__(self , type , value , traceback):<br />
self.cursor.close()<br />
Es handelt sich hierbei letztlich nur um einen<br />
sogenannten „Wrapper“, der die Verwendung<br />
von SQLite-Cursorn mit with ermöglicht. Später<br />
könnte ein Aufruf wie folgt aussehen:<br />
1 with Cursor(connection) as cursor:<br />
2 cursor.machetwas()<br />
connection ist dabei eine Referenz auf ein<br />
SQLite-Connection-Objekt, das eine offene Datenbankverbindung<br />
verwaltet. In Zeile 1 wird<br />
nun zunächst eine Instanz der Cursor-Klasse<br />
erstellt und connection als Parameter übergeben.<br />
In der Methode __init__ wird die Referenz<br />
auf das Connection-Objekt an das Attribut<br />
self.connection gebunden. Erst danach<br />
wird durch den with-Block die Methode<br />
__enter__ des Cursor-Objektes aufgerufen.<br />
Hier wird nun das SQLite-Cursor-Objekt durch<br />
den Aufruf self.connection.cursor() erstellt.<br />
Das Objekt wird an das Attribut self.cursor gebunden<br />
und mittels des Schlüsselwortes return<br />
zurückgegeben. Da der Rückgabewert der Methode<br />
__enter__ in with-Blöcken an den hinter<br />
as angegebenen Namen gebunden wird, steht<br />
nun eine Referenz auf das SQLite-Cursor-Objekt<br />
unter dem Namen cursor zur Verfügung. In Zeile<br />
2 des Beispiels kann so bequem auf das SQLite-<br />
Cursor-Objekt zugegriffen werden. Mit dem Verlassen<br />
des with-Blocks würde schließlich die<br />
Methode __exit__ aufgerufen werden, in der<br />
das Cursor-Objekt korrekt geschlossen wird.<br />
© <strong>freiesMagazin</strong> CC-BY-SA 3.0 Ausgabe 03/2011 22