Frage

Ich habe eine Methode in meinem Python-Code, die ein Tupel zurückgibt – eine Zeile aus einer SQL-Abfrage.Nehmen wir an, es hat drei Felder:(Job-ID, Label, Benutzername)

Um die Weitergabe zwischen Funktionen zu vereinfachen, habe ich das gesamte Tupel als Variable namens „Job“ übergeben.Irgendwann möchte ich jedoch an die einzelnen Punkte herankommen, deshalb habe ich Code wie diesen verwendet:(Job-ID, Label, Benutzername) = Job

Mir ist jedoch klar geworden, dass dies ein Wartungsalptraum ist, da ich jetzt nie mehr neue Felder zum Ergebnissatz hinzufügen kann, ohne meinen gesamten vorhandenen Code zu zerstören.Wie hätte ich das schreiben sollen?

Hier sind meine zwei besten Vermutungen:(JobID, Etikett, Benutzername) = (Job [0], Job [1], Job [2]) ... aber das skaliert nicht gut, wenn Sie 15 ... 20 Felder haben

oder die Ergebnisse der SQL-Abfrage sofort in ein Wörterbuch umzuwandeln und weiterzugeben (ich habe keine Kontrolle darüber, dass es als Tupel beginnt, das ist für mich behoben)

War es hilfreich?

Lösung

Ich würde sagen, dass ein Wörterbuch definitiv der beste Weg ist, dies zu tun.Es ist leicht erweiterbar, ermöglicht es Ihnen, jedem Wert einen sinnvollen Namen zu geben, und Python verfügt über zahlreiche integrierte Sprachfunktionen zur Verwendung und Bearbeitung von Wörterbüchern.Wenn Sie später weitere Felder hinzufügen müssen, müssen Sie lediglich den Code ändern, der das Tupel in ein Wörterbuch umwandelt, und den Code, der die neuen Werte tatsächlich verwendet.

Zum Beispiel:

job={}
job['jobid'], job['label'], job['username']=<querycode>

Andere Tipps

@Staale

Es gibt einen besseren Weg:

job = dict(zip(keys, values))

Das ist eine alte Frage, aber...

Ich würde vorschlagen, in dieser Situation ein benanntes Tupel zu verwenden: Sammlungen.namedtuple

Dies ist insbesondere der Teil, den Sie nützlich finden würden:

Unterklassen sind für das Hinzufügen neuer, gespeicherter Felder nicht sinnvoll.Erstellen Sie stattdessen einfach einen neuen benannten Tupeltyp aus dem _fields-Attribut.

Vielleicht ist das für Ihren Fall übertrieben, aber ich wäre versucht, eine „Job“-Klasse zu erstellen, die das Tupel als Konstruktorargument verwendet und entsprechende Eigenschaften darauf hat.Ich würde dann stattdessen Instanzen dieser Klasse weitergeben.

Ich würde ein Wörterbuch verwenden.Sie können das Tupel folgendermaßen in ein Wörterbuch umwandeln:

values = <querycode>
keys = ["jobid", "label", "username"]
job = dict([[keys[i], values [i]] for i in xrange(len(values ))])

Dadurch wird zunächst ein Array [["jobid", val1], ["label", val2], ["username", val3]] erstellt und dieses dann in ein Wörterbuch konvertiert.Wenn sich die Reihenfolge oder Anzahl der Ergebnisse ändert, müssen Sie lediglich die Liste der Schlüssel ändern, um sie an das neue Ergebnis anzupassen.

PS: Ich bin selbst noch frisch in Python, daher gibt es möglicherweise bessere Möglichkeiten, dies zu tun.

Eine alte Frage, aber da sie niemand erwähnt hat, füge ich diese aus dem Python-Kochbuch hinzu:

Rezept 81252:Verwenden von dtuple für den flexiblen Zugriff auf Abfrageergebnisse

Dieses Rezept ist speziell für den Umgang mit Datenbankergebnissen konzipiert und die Dtuple-Lösung ermöglicht Ihnen den Zugriff auf die Ergebnisse nach Name ODER Indexnummer.Dadurch wird vermieden, dass Sie per Index auf alles zugreifen müssen, was, wie in Ihrer Frage erwähnt, sehr schwierig zu pflegen ist.

Bei einem Tupel wird es immer mühsam sein, Felder hinzuzufügen oder zu ändern.Sie haben Recht, dass ein Wörterbuch viel besser ist.

Wenn Sie etwas mit einer etwas benutzerfreundlicheren Syntax wünschen, sollten Sie sich die Antworten ansehen diese Frage über ein einfaches 'strukturähnliches' Objekt.Auf diese Weise können Sie beispielsweise einen Gegenstand herumreichen job, und greifen Sie noch einfacher auf seine Felder zu als bei einem Tupel oder Diktat:

job.jobId, job.username = jobId, username

Wenn Sie das MySQLdb-Paket verwenden, können Sie Ihre Cursorobjekte so einrichten, dass sie Diktate anstelle von Tupeln zurückgeben.

import MySQLdb, MySQLdb.cursors
conn = MySQLdb.connect(..., cursorclass=MySQLdb.cursors.DictCursor)
cur = conn.cursor() # a DictCursor
cur2 = conn.cursor(cursorclass=MySQLdb.cursors.Cursor) # a "normal" tuple cursor

Wie wäre es damit:

class TypedTuple:
    def __init__(self, fieldlist, items):
       self.fieldlist = fieldlist
       self.items = items
    def __getattr__(self, field):
       return self.items[self.fieldlist.index(field)]

Sie könnten dann Folgendes tun:

j = TypedTuple(["jobid", "label", "username"], job)
print j.jobid

Es sollte leicht zu tauschen sein self.fieldlist.index(field) mit einer Wörterbuchsuche später ...Bearbeiten Sie einfach Ihre __init__ Methode!So etwas wie Staale.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top