Seite 1 von 1

cmpfunc generisch produzieren

Verfasst: Montag 29. Oktober 2007, 09:43
von wivaxing
Hi,

ich verwende aktuell noch python 2.2.3 und habe mir gerade einen ganzen Schwung von Compare Funktionen gebaut, um eine Listen mit externen C++ Klassen zu sortieren.

Die Compare-Funktionen sind aber alle Leicht gleichförmig

Code: Alles auswählen

def cmp_name(x,y):
	if x.name < y.name:
		return -1
   # [..] und so weiter

def cmp_name_rev(x,y):
    return -1 * cmp_name(x,y)
Die Funktionen sind alle in der Form gleich, jetzt fragt ich mich ob dies nicht generisch geht. Also eine Art:
list.sort(gencmpfunc("name"))
Diese Funktion liefert wieder eine spezialisierte cmpfunc-Funktion zurück. Ich habe schon einigermaßen gesehen, wie das gehen könnte - die Frage: kann ich zur Laufzeit mit dem Namen repräsentiert durch einen String auf einen Member einer Klasse zugreifen - also von "name" zu element.name?

Vielen dank :)

Verfasst: Montag 29. Oktober 2007, 10:02
von BlackJack
Die Stichworte sind `getattr()` und "closure". Ungetestet:

Code: Alles auswählen

def make_attr_cmp(attribute_name):
    def cmp_(a, b):
        return cmp(getattr(a, attribute_name), getattr(b, attribute_name))
    
    def cmp_reverse(a, b):
        return -1 * cmp_(a, b)
    
    return cmp_, cmp_reverse


cmp_name, cmp_name_reverse = make_attr_cmp('name')

Verfasst: Montag 29. Oktober 2007, 11:21
von wivaxing
Vielen Dank!

Ich bekomme da immer eine Exception der Form

Code: Alles auswählen

Traceback (most recent call last):
  File "Test.py", line 230, in ?
    printStatus(dfliste)
  File "Test.py", line 182, in printStatus
    dfliste.sort( cmpfunc )
TypeError: 'NoneType' object is not callable


Ganznebenbei sind meine manuellen cmpfuncs schon deutlich kleiner geworden eifnach durch die Verwendung von cmp(x,y). Und dies mit dem getattr(..) funktioniert auch, nur irgendwie noch nicht in der Definition zusammen. Vielen Dank schonmal, mal schauen ob ich meinen Fehler hier finde..

Verfasst: Montag 29. Oktober 2007, 11:49
von BlackJack
Zeig mal den Code wie Du `cmpfunc` denn nun definiert hast. Der Name scheint ja an `None` gebunden zu sein.

Verfasst: Montag 29. Oktober 2007, 14:30
von wivaxing
Ich bin gar nicht mal sicher, was da eben falsch war - auf jeden Fall funktioniert es jetzt! Danke :)