Galileo Computing < openbook > Galileo Computing - Professionelle Bücher. Auch für Einsteiger.
Professionelle Bücher. Auch für Einsteiger.

Inhaltsverzeichnis
1 Einleitung
2 Überblick über Python
3 Die Arbeit mit Python
4 Der interaktive Modus
5 Grundlegendes zu Python-Programmen
6 Kontrollstrukturen
7 Das Laufzeitmodell
8 Basisdatentypen
9 Benutzerinteraktion und Dateizugriff
10 Funktionen
11 Modularisierung
12 Objektorientierung
13 Weitere Spracheigenschaften
14 Mathematik
15 Strings
16 Datum und Zeit
17 Schnittstelle zum Betriebssystem
18 Parallele Programmierung
19 Datenspeicherung
20 Netzwerkkommunikation
21 Debugging
22 Distribution von Python-Projekten
23 Optimierung
24 Grafische Benutzeroberflächen
25 Python als serverseitige Programmiersprache im WWW mit Django
26 Anbindung an andere Programmiersprachen
27 Insiderwissen
28 Zukunft von Python
A Anhang
Stichwort

Download:
- ZIP, ca. 4,8 MB
Buch bestellen
Ihre Meinung?

Spacer
 <<   zurück
Python von Peter Kaiser, Johannes Ernesti
Das umfassende Handbuch - Aktuell zu Python 2.5
Buch: Python

Python
gebunden, mit CD
819 S., 39,90 Euro
Galileo Computing
ISBN 978-3-8362-1110-9
Pfeil 13 Weitere Spracheigenschaften
  Pfeil 13.1 Exception Handling
    Pfeil 13.1.1 Eingebaute Exceptions
    Pfeil 13.1.2 Werfen einer Exception
    Pfeil 13.1.3 Abfangen einer Exception
    Pfeil 13.1.4 Eigene Exceptions
    Pfeil 13.1.5 Erneutes Werfen einer Exception
  Pfeil 13.2 List Comprehensions
  Pfeil 13.3 Docstrings
  Pfeil 13.4 Generatoren
  Pfeil 13.5 Iteratoren
  Pfeil 13.6 Interpreter im Interpreter
  Pfeil 13.7 Geplante Sprachelemente
  Pfeil 13.8 Die with-Anweisung
  Pfeil 13.9 Function Decorator
  Pfeil 13.10 assert
  Pfeil 13.11 Weitere Aspekte der Syntax
    Pfeil 13.11.1 Umbrechen langer Zeilen
    Pfeil 13.11.2 Zusammenfügen mehrerer Zeilen
    Pfeil 13.11.3 String conversions


Galileo Computing - Zum Seitenanfang

13.9 Function Decorator  topZur vorigen Überschrift

Aus dem Kapitel über objektorientierte Programmierung kennen Sie sicherlich noch die Built-in Function staticmethod, die folgendermaßen verwendet wurde:

class MeineKlasse(object):
def methode(): pass
methode2 = staticmethod(methode)

Durch diese Schreibweise wird zunächst eine Methode angelegt und nachher durch die Built-in Function staticmethod modifiziert. Die angelegte Methode wird dann mit dem modifizierten Funktionsobjekt überschrieben.

Diese Art, staticmethod anzuwenden, ist zwar richtig und funktioniert, ist aber gleichzeitig auch unidiomatisch und nicht gerade gut lesbar. Aus diesem Grund unterstützt Python eine eigene Notation, um den obigen Code lesbarer zu gestalten. Das folgende Beispiel ist zu dem vorherigen äquivalent:

class MeineKlasse(object):
@staticmethod def methode(): pass

Die Funktion, die die angelegte Methode modifizieren soll, wird nach einem @–Zeichen vor die Methodendefinition geschrieben. Eine solche Notation wird Function Decorator genannt. Allerdings sind Function Decorators nicht auf den Einsatz mit staticmethod beschränkt, vielmehr können Sie beliebige Decorators erstellen. Auf diese Weise kann eine Funktion durch bloßes Hinzufügen eines Decorators um eine gewisse Funktionalität erweitert werden.

Function Decorator können nicht nur auf Methoden angewendet werden, sondern genauso auf Funktionen. Zudem können sie ineinander verschachtelt werden, wie folgendes Beispiel zeigt:

@dec1 
@dec2 
def funktion(): 
    pass

Diese Funktionsdefinition ist äquivalent zu folgendem Code:

def funktion(): 
    pass 
funktion = dec1(dec2(funktion))

Es erübrigt sich zu sagen, dass sowohl dec1 als auch dec2 implementiert werden müssen, bevor die Beispiele lauffähig sind.

Das jetzt folgende Beispiel soll einen interessanten Ansatz zum Cachen (dt. Zwischenspeichern) von Funktionsaufrufen zeigen, sodass die Ergebnisse von komplexen Berechnungen automatisch gespeichert werden. Diese können dann beim nächsten Funktionsaufruf mit den gleichen Parametern wiedergegeben werden, ohne die Berechnungen erneut durchführen zu müssen. Das Caching einer Funktion soll allein durch Angabe eines Function Decorators erledigt werden, also ohne in die Funktion selbst einzugreifen, und zudem mit beliebigen Funktionsschnittstellen, also beliebigen Funktionen arbeiten können. Dazu sehen wir uns zunächst einmal die Definition der Berechnungsfunktion an, die in diesem Fall die Fakultät einer ganzen Zahl berechnet, inklusive Function Decorator:

@CacheDecorator() 
def fak(n): 
    ergebnis = 1 
    for i in xrange(2, n+1): 
        ergebnis *= i 
    return ergebnis

Die Berechnung einer Fakultät sollte Ihnen inzwischen geläufig sein. Was hier allerdings interessant ist, ist der Function Decorator, denn es handelt sich hierbei nicht um eine Funktion, sondern um eine Klasse namens CacheDecorator, die im Decorator instanziiert wird. Sie erinnern sich sicherlich, dass eine Klasse durch Implementieren der Magic Function __call__ aufrufbar gemacht werden kann und sich damit wie ein Funktionsobjekt verhält. Wir müssen diesen Umweg gehen, da wir die Ergebnisse der Berechnungen so speichern müssen, dass sie auch in späteren Aufrufen des Decorators noch verfügbar sind. Das ist mit einer Funktion nicht möglich, wohl aber mit einer Klasse. Die Definition der Decorator-Klasse sieht folgendermaßen aus:

class CacheDecorator(object):
def __init__(self): self.cache = {} self.func = None
def cachedFunc(self, *args): if args not in self.cache: self.cache[args] = self.func(*args) return self.cache[args]
def __call__(self, func): self.func = func return self.cachedFunc

Im Konstruktor der Klasse CacheDecorator wird ein leeres Dictionary für die zwischengespeicherten Werte angelegt. Neben dem Konstruktor ist unter anderem die Methode __call__ implementiert. Durch diese Methode werden Instanzen der Klasse aufrufbar, können also wie ein Funktionsobjekt verwendet werden. Um als Function Decorator verwendet werden zu können, muss die Methode __call__ ein Funktionsobjekt als Parameter akzeptieren und ein Funktionsobjekt zurückgeben, das fortan als veränderte Version der ursprünglich angelegten Funktion mit dieser assoziiert wird. In diesem Fall gibt __call__ das Funktionsobjekt der Methode cachedFunc zurück.

Die Methode cachedFunc soll also fortan anstelle der ursprünglich angelegten Funktion aufgerufen werden. Damit sie ihre Aufgabe erledigen kann, hat sie Zugriff auf das Funktionsobjekt der eigentlichen Funktion, das von dem Attribut self.func referenziert wird. Die Methode cachedFunc akzeptiert beliebig viele positional arguments, da sie später für beliebige Funktionen und damit beliebige Funktionsschnittstellen arbeiten muss. Diese Argumente sind innerhalb der Methode als Tupel verfügbar.

Jetzt wird geprüft, ob das Tupel mit den übergebenen Argumenten bereits als Schlüssel im Dictionary self.cache existiert. Wenn ja, wurde die Funktion bereits mit exakt den gleichen Argumenten aufgerufen und der im Cache gespeicherte Rückgabewert kann direkt zurückgegeben werden. Wenn der Schlüssel nicht vorhanden ist, wird die Berechnungsfunktion self.func mit den übergebenen Argumenten aufgerufen und das Ergebnis im Cache gespeichert. Anschließend wird es zurückgegeben.

Um zu testen, ob das Speichern der Werte funktioniert, wird das Beispiel um zwei Ausgaben erweitert, je nachdem, ob ein Ergebnis neu berechnet oder aus dem Cache geladen wurde. Und tatsächlich, es funktioniert:

>>> fak(10) 
Ergebnis berechnet 
3628800 
>>> fak(20) 
Ergebnis berechnet 
2432902008176640000L 
>>> fak(20) 
Ergebnis geladen 
2432902008176640000L 
>>> fak(10) 
Ergebnis geladen 
3628800

Wie Sie sehen, wurden die ersten beiden Ergebnisse berechnet, während die letzten beiden aus dem internen Cache geladen wurden. Diese Form des Cachings könnte je nach Anwendungsbereich und Komplexität der Berechnung erhebliche Geschwindigkeitsvorteile bieten.



Ihr Kommentar

Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen.






 <<   zurück
  
  Zum Katalog
Zum Katalog: Python






Python
bestellen
 Ihre Meinung?
Wie hat Ihnen das <openbook> gefallen?
Ihre Meinung

 Buchtipps
Zum Katalog: Linux






 Linux


Zum Katalog: Ubuntu GNU/Linux






 Ubuntu GNU/Linux


Zum Katalog: Praxisbuch Web 2.0






 Praxisbuch Web 2.0


Zum Katalog: UML 2.0






 UML 2.0


Zum Katalog: Praxisbuch Objektorientierung






 Praxisbuch Objektorientierung


Zum Katalog: Einstieg in SQL






 Einstieg in SQL


Zum Katalog: IT-Handbuch für Fachinformatiker






 IT-Handbuch für Fachinformatiker


 Shopping
Versandkostenfrei bestellen in Deutschland und Österreich
InfoInfo





Copyright © Galileo Press 2008
Für Ihren privaten Gebrauch dürfen Sie die Online-Version natürlich ausdrucken. Ansonsten unterliegt das <openbook> denselben Bestimmungen, wie die gebundene Ausgabe: Das Werk einschließlich aller seiner Teile ist urheberrechtlich geschützt. Alle Rechte vorbehalten einschließlich der Vervielfältigung, Übersetzung, Mikroverfilmung sowie Einspeicherung und Verarbeitung in elektronischen Systemen.


[Galileo Computing]

Galileo Press, Rheinwerkallee 4, 53227 Bonn, Tel.: 0228.42150.0, Fax 0228.42150.77, info@galileo-press.de