Durch Argumente iterieren...

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
Benutzeravatar
BlackVivi
User
Beiträge: 762
Registriert: Samstag 9. Dezember 2006, 14:29
Kontaktdaten:

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!)
schlangenbeschwörer
User
Beiträge: 419
Registriert: Sonntag 3. September 2006, 15:11
Wohnort: in den weiten von NRW
Kontaktdaten:

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ß
Benutzeravatar
BlackVivi
User
Beiträge: 762
Registriert: Samstag 9. Dezember 2006, 14:29
Kontaktdaten:

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...
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

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()``.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
BlackVivi
User
Beiträge: 762
Registriert: Samstag 9. Dezember 2006, 14:29
Kontaktdaten:

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.
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

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
BlackJack

BlackVivi behandelt dort einen `IndexError`, der kommt sicher nicht vom `get()` tritt also auch bei Dir unbehandelt auf.
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Stimmt! Das müsste dann ein KeyError sein. :oops:
Benutzeravatar
BlackVivi
User
Beiträge: 762
Registriert: Samstag 9. Dezember 2006, 14:29
Kontaktdaten:

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!)
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

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
Benutzeravatar
BlackVivi
User
Beiträge: 762
Registriert: Samstag 9. Dezember 2006, 14:29
Kontaktdaten:

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...
Antworten