Umgang mit langen Argumentendictionaries in Funktionen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

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
Beyond
User
Beiträge: 227
Registriert: Freitag 6. September 2002, 19:06
Kontaktdaten:

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
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

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:
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
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Hoi

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

Gruß,
Christian
Antworten