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

Umgang mit langen Argumentendictionaries in Funktionen

Beitragvon CM » Dienstag 1. März 2005, 13:50

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

Beitragvon Beyond » Dienstag 1. März 2005, 20:42

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
Moderator
Beiträge: 8458
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Beitragvon jens » Dienstag 1. März 2005, 21:27

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

Beitragvon BlackJack » Dienstag 1. März 2005, 23:13

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:

Beitragvon CM » Mittwoch 2. März 2005, 10:31

Hoi

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

Gruß,
Christian

Wer ist online?

Mitglieder in diesem Forum: Google [Bot]