Seite 1 von 1

Durch Argumente iterieren...

Verfasst: Samstag 20. Oktober 2007, 17:39
von BlackVivi
Ich weiß nicht, wie ich das am besten beschreiben soll... Ich hab'ne Funktion, die heißt add_contact und erwartet eben eine bestimmte Anzahl von Argumente erwartet...

Code: Alles auswählen

    def add_contact(self, first_name = "", last_name = "", adress = "",
                    birthday = "", email = "", telephone = ""):
        try:
            id = str(int(self.root[0][-1].get("id")) + 1)
        except IndexError:
            id = "0"
        self.root.find("adresses").append(ET.Element("adress"))
        self.root.find("adresses")[-1].attrib['id'] = id
        self.root.find("adresses")[-1].append(ET.Element("first_name"))
        self.root.find("adresses")[-1].find("first_name").text = first_name
        self.root.find("adresses")[-1].append(ET.Element("last_name"))
        self.root.find("adresses")[-1].find("last_name").text = last_name
        self.root.find("adresses")[-1].append(ET.Element("adress"))
        self.root.find("adresses")[-1].find("adress").text = adress
        self.root.find("adresses")[-1].append(ET.Element("birthday"))
        self.root.find("adresses")[-1].find("birthday").text = birthday
        self.root.find("adresses")[-1].append(ET.Element("email"))
        self.root.find("adresses")[-1].find("email").text = email
        self.root.find("adresses")[-1].append(ET.Element("telephone"))
        self.root.find("adresses")[-1].find("telephone").text = telephone
(Die Einrückung kommt davon, dass's aus einer Klasse kommt... Und ich könnte ja auch zum Beispiel adresses = self.root.find("adresses") benutzen, um zumindest den code nicht so gewaltig ausshen zu lassen, hab's aber absichtlich weggelassen, um die Redundanz zu verdeutlchen)

Wie ihr seht, ist da'ne Menge Redundanz zu sehen. Könnte ich irgendwie ein iterierbares Argument aufnehmen, bei dem trotzdem deutlich eine Unterscheidung zwischen first_name, last_name usw zu sehen ist?... *args wäre ja eine Möglichkeit, jedoch sieht man ja dann nicht, welche Elemente erwartet werden. Vielleicht kennt ja jemand'ne Möglichkeit...

(Ich hoffe ich hab's einigermassen gut beschrieben. Vielen dank im Vorraus!)

Verfasst: Samstag 20. Oktober 2007, 17:54
von schlangenbeschwörer
Hi!
Wenn du nicht mit *args oder **kwargs arbeiten willst, musst du halt die Argumente in ne liste packen und darüber iterieren.

Code: Alles auswählen

args = (("first_name", first_name), ("last_name", last_name),...)
for argname, value in args:
    self.root.find("adresses")[-1].append(ET.Element(argname))
    self.root.find("adresses")[-1].find(argname).text = value
(hab ich dich richtig verstanden)

Gruß

Verfasst: Samstag 20. Oktober 2007, 18:16
von BlackVivi
Auf deinen Tip hin hab ich das nu so gelöst oO

Code: Alles auswählen

    def add_contact(self, first_name = "", last_name = "",
                     adress = "", birthday = "", email = "", telephone = ""):
        try:
            id = str(int(self.root[0][-1].get("id")) + 1)
        except IndexError:
            id = "0"
        self.root.find("adresses").append(ET.Element("adress"))
        self.root.find("adresses")[-1].attrib['id'] = id
        args = {"first_name": first_name,
                "last_name": last_name,
                "adress": adress,
                "birthday": birthday,
                "email": email,
                "telephone": telephone}
        last_adress = self.root.find("adresses")[-1]
        for data in args.iterkeys():
            last_adress.append(ET.Element(data))
            last_adress.find(data).text = args[data]
Vielleicht hat jemand anders noch'ne bessere Idee...

Verfasst: Samstag 20. Oktober 2007, 18:51
von Leonidas
Na klar, das geht mit noch etwas weniger Redundanz indem du die Argumentliste mit dem ``inspect``-Modul abarbeitest, wie hier beschrieben. Funktioniert danach auch wenn du mehr Parameter hinzufügst.

Die Parameter bekommst du mit ``inspect.getargspec(add_contact)[0][1:]``, deren Werte guckst du in dem dict ``locals()`` nach, das wars schon.

Apropos: PEP8-Alarm (siehe die Argumentliste von ``add_contact``) und du überschreibst das Built-in ``id()``.

Verfasst: Samstag 20. Oktober 2007, 19:12
von BlackVivi
Leonidas hat geschrieben:Na klar, das geht mit noch etwas weniger Redundanz indem du die Argumentliste mit dem ``inspect``-Modul abarbeitest, wie hier beschrieben. Funktioniert danach auch wenn du mehr Parameter hinzufügst.

Die Parameter bekommst du mit ``inspect.getargspec(add_contact)[0][1:]``, deren Werte guckst du in dem dict ``locals()`` nach, das wars schon.

Apropos: PEP8-Alarm (siehe die Argumentliste von ``add_contact``) und du überschreibst das Built-in ``id()``.
Dankeschön. Ich werd mir für ID was anderes suchen.

Verfasst: Sonntag 21. Oktober 2007, 09:28
von HWK
BlackVivi hat geschrieben:

Code: Alles auswählen

        try:
            id = str(int(self.root[0][-1].get("id")) + 1)
        except IndexError:
            id = "0"
wäre einfacher:

Code: Alles auswählen

id_ = str(int(self.root[0][-1].get('id', -1)) + 1)
MfG
HWK

Verfasst: Sonntag 21. Oktober 2007, 10:03
von BlackJack
BlackVivi behandelt dort einen `IndexError`, der kommt sicher nicht vom `get()` tritt also auch bei Dir unbehandelt auf.

Verfasst: Sonntag 21. Oktober 2007, 11:26
von HWK
Stimmt! Das müsste dann ein KeyError sein. :oops:

Verfasst: Sonntag 21. Oktober 2007, 11:51
von BlackVivi
Ich versuche das letzte Elemente in bei den Nodes zu bekommen, falls kein letztes Element besteht, gibt es einfach keins und ich lege eins mit der Nummer 0 an. Vielleicht ein bissel blöd gelöst, aber es funktioniert... Und mir ist spontan keine andere Möglichkeit eingefallen.

(Das Problem dabei ist nur, wenn man jetzt 20 Kontakte hat, darauf in der Mitte so 3 Kontakte löscht, hat der letzte Kontakt trotzdem die Nummer 20... Ich könnte es iterieren mit einer range und beim ersten KeyError es das Element erstellen... Warte, keine schlechte Idee!)

Verfasst: Sonntag 21. Oktober 2007, 12:32
von HWK
Brauchst Du denn unbedingt einen Eintrag 'id'? Würde als id nicht die Position des Elements in der Liste ausreichen? Dann hätte sich auch das Problem beim Löschen erübrigt.
Statt Deines 'try...except' wäre doch auch 'if self.root[0]...else' möglich.
MfG
HWK

Verfasst: Sonntag 21. Oktober 2007, 12:52
von BlackVivi
HWK hat geschrieben:Brauchst Du denn unbedingt einen Eintrag 'id'? Würde als id nicht die Position des Elements in der Liste ausreichen? Dann hätte sich auch das Problem beim Löschen erübrigt.
Statt Deines 'try...except' wäre doch auch 'if self.root[0]...else' möglich.
MfG
HWK
Hmpf, find es mit ID bzw. jetzt NR irgendwie hübscher und eindeutiger. Aber ich kann's ja mal ohne ausprobieren..

Zu deinem Vorschlag mit dem IF:
Das würde es, finde ich, für mich nur unnötig schwerer machen...