Was ist die am besten gepflegte allgemeine Funktionen-Implementierung für Python?

8

Eine generische Funktion wird basierend auf dem Typ aller ihrer Argumente ausgelöst. Der Programmierer definiert mehrere Implementierungen einer Funktion. Der richtige wird zum Zeitpunkt des Anrufs basierend auf den Typen seiner Argumente ausgewählt. Dies ist unter anderem nützlich für die Objektanpassung. Python hat einige generische Funktionen einschließlich len() .

Diese Pakete ermöglichen Code, der wie folgt aussieht:

%Vor%

Ein weniger dummes Beispiel, über das ich in letzter Zeit nachgedacht habe, wäre eine Webkomponente, die einen Benutzer benötigt. Anstatt ein bestimmtes Web-Framework zu benötigen, müsste der Integrator nur etwas schreiben wie:

%Vor%

Python hat einige generische Funktionen implementiert. Warum sollte ich einen über den anderen wählen? Wie wird diese Implementierung in Anwendungen verwendet?

Ich kenne Zopes zope.component.queryAdapter(object, ISomething) . Der Programmierer registriert einen aufrufbaren Adapter, der eine bestimmte Objektklasse als Argument akzeptiert und etwas mit der Schnittstelle kompatibles zurückgibt. Es ist eine nützliche Möglichkeit, Plugins zuzulassen. Im Gegensatz zum Monkey-Patching funktioniert es sogar, wenn ein Objekt sich an mehrere Interfaces mit denselben Methodennamen anpassen muss.

    
joeforker 18.09.2009, 14:54
quelle

3 Antworten

7

Ich würde die PEAK-Regeln Bibliothek von P. Eby empfehlen. Vom selben Autor (obwohl veraltet) ist das RuleDispatch -Paket (der Vorgänger der PEAK-Regeln). Letzteres wird nicht mehr aufrechterhalten IIRC.

PEAK-Rules hat viele nette Features, eines davon ist, dass es (naja, nicht einfach, aber) erweiterbar ist. Neben dem "klassischen" Versand auf Typen bietet es die Möglichkeit, beliebige Ausdrücke als "Wächter" zu versenden.

Die Funktion len() ist keine echte generische Funktion (zumindest im Sinne der oben erwähnten Pakete, und auch in diesem Sinne wird dieser Begriff in Sprachen wie Common Lisp , Dylan oder Cecil ), da es einfach eine ist bequeme Syntax für einen Aufruf einer speziell benannten (aber ansonsten regulären) Methode:

%Vor%

Beachten Sie auch, dass dies nur Single-Dispatch ist, dh der eigentliche Empfänger ( s im obigen Code) bestimmt die aufgerufene Methodenimplementierung. Und sogar eine hypothetische

%Vor%

ist immer noch eine Single-Dispatch-Funktion, da nur der Empfänger verwendet wird, wenn die aufzurufende Methode aufgelöst wird. Die restlichen Argumente werden einfach weitergegeben, beeinflussen aber nicht die Methodenauswahl.

Dies unterscheidet sich von Mehrfach-Dispatch, wo es keinen dedizierten Empfänger gibt, und alle Argumente werden verwendet, um die tatsächliche Methodenimplementierung zu finden, die aufgerufen werden soll. Das ist es, was die ganze Sache lohnenswert macht. Wenn es nur eine seltsame Art von syntaktischem Zucker wäre, würde sich niemand damit beschäftigen, IMHO.

%Vor%

In diesem Beispiel ein Anruf wie

%Vor%

berücksichtigt beide Argumente, um zu entscheiden, welche Methode tatsächlich aufgerufen werden soll.

Für ein nettes Anwendungsszenario generischer Funktionen in Python empfehle ich den Refactored-Code der zu lesen peak.security , was eine sehr elegante Lösung für die Zugriffserlaubnisprüfung mit generischen Funktionen bietet (mit RuleDispatch ).

    
Dirk 18.09.2009, 15:02
quelle
0

Sie können eine Konstruktion wie folgt verwenden:

%Vor%

In diesem Fall wird args eine Liste aller unbenannten Argumente sein, und kwargs wird ein Dictionary der genannten sein. Von hier aus können Sie ihre Typen erkennen und entsprechend handeln.

    
defrex 18.09.2009 15:04
quelle
0

Ich kann den Punkt in diesen "generischen" Funktionen nicht sehen. Es klingt wie einfacher Polymorphismus.

Ihre "generischen" Funktionen können so implementiert werden, ohne auf eine Laufzeittyp-Identifikation zurückgreifen zu müssen.

%Vor%     
S.Lott 18.09.2009 15:23
quelle

Tags und Links