Seite 1 von 1

Umgang mit langen Argumentendictionaries in Funktionen

Verfasst: Dienstag 1. März 2005, 13:50
von CM
Hi

hat jemand eine elegantere Lösung für folgendes Problem als ich? Meine finde ich nämlich reichlich umständlich ...

Ich möchte eine Klasse initialisieren mit vielen Attributen. Nur eines muß (!) gegeben werden, alle anderen sind optional. Im Grunde ähnelt dieses Problem dem einem gewöhnlichen Funktionsaufrufes mit vielen optional Argumenten.
Meine Lösung (in Pseudo-Code):

Code: Alles auswählen

def __init__(self,data,**keywords):
	possible_keys = ['name','meta','minimum','maximum',...]
	keys = keywords.keys()
	#teste ob nur erlaube Schüssel verwendet werden
	for kw in keys:
		if kw not in possible_keys:
			raise KeyError: "description"
		#hier mein eigendliches Problem: muß ich wirklich jeden Schlüssel testen?
		if kw = 'name': self.name = keywords[kw]
		elif kw = 'meta' : self.meta = keywords[kw]
		...
		#und anschließend die default-Werte setzen?
		try: self.name
		except: self.name = None
		try: self.meta
		except: self.meta = None
		#und dann erst das Handling des eigentlichen Datensatzes:
		try: self.data = #irgendwas mit Numarray ...
Das macht für eine lange Liste von möglichen Argumenten ziemlich viele Zeilen Code. Oder kennt jemand eine Alternative?

Vielen Dank für jeden Tipp,
Christian

Verfasst: Dienstag 1. März 2005, 20:42
von Beyond
1.) Mit DICT.setdefault die Defaultwerte setzen. (Das ist eine gewöhnliche Fkt. und damit werden die Argumente immer ausgewertet, wenn Du aber nicht viel für den Default rechnest ist's egal)
2.) mit setattr(obj, 'attributName', attributWert) alles in das Objekt füttern.
Dazu durchläufst du das DICT mit

for (name, value) inDICT.items():
...

cu beyond

Verfasst: Dienstag 1. März 2005, 21:27
von jens
Warum übergibst du nicht ein Dict und arbeitest dann auch weiter damit (self.Dict = Dict)... Kannst ja die Werte auch mit possible_keys wie du es hast überprüfen... Default-Werte kannst du ja auch setzten...

Also ungefähr so:

Code: Alles auswählen

def __init__( self, Dict ):
        possible_keys = ['name','meta','minimum','maximum',...]
        for key in Dict.keys(): # Überprüfen
            if key not in possible_keys:
                raise KeyError: "description" 
        
        self.Dict = { 1:"0",2:"0" } # Default Werte setzten
        for k,i in MyDict.iteritems(): # Gegebene Werte überschreiben
            self.Dict[k] = i
            
        print self.Dict
Das überschreiben der Default-Werte mit den gegebenen geht mit sicherheit auch besser, weiß gerade aber nicht wie :oops:

Verfasst: Dienstag 1. März 2005, 23:13
von BlackJack
Ich würde mich Jens anschliessen und das Dictionary als Attribut verwenden. Die beiden Schleifen kann man zusammenziehen:

Code: Alles auswählen

def __init__(self, **kwargs):
    self.dictionary = { 'name': 'Ich', 'minimum': 0, 'maximum': 42 }
    for key, value in kwargs.iteritems():
        if not key in self.dictionary:
            raise TypeError("unexpected keyword argument %r" % key)
        self.dictionary[key] = value

Verfasst: Mittwoch 2. März 2005, 10:31
von CM
Hoi

ja, ihr habt da eine gute Idee - ich glaube, das spart mir wirklich einige Mühen. Vielen Dank.

Gruß,
Christian