Gibt es einen empfohlenen / allgemein akzeptierten Codierungsstil für Situationen, in denen eine Funktion ein Tupel von Werten zurückgibt, aber anschließend nur einer dieser Werte verwendet wird (beachten Sie, dass dies hauptsächlich für Bibliotheksfunktionen gedacht ist, die ich nicht ändern kann - einen Wrapper schreiben Der Anruf ist wahrscheinlich ein bisschen übertrieben ...)? Anstatt zu tun
a, b, c = foo()
und dann einfach nicht b
und verwenden c
, welche der folgenden Varianten sollte bevorzugt werden (oder gibt es eine andere?):
Variante 1 (Unterstrich)
a, _, _ = foo()
(Das ist sehr klar und einfach, kann aber _ = gettext.gettext
in vielen Anwendungen, die Übersetzungen verwenden, zu Konflikten führen. )
Variante 2 (Dummy-Name)
a, unused, unused = foo()
(nicht sehr ansprechend, denke ich, dasselbe gilt für andere Namen wie dummy
)
Variante 3 (Index)
a = foo()[0]
(für mich ()[0]
sieht das unpythonisch aus ...)
quelle
a, b = foo()[0:2]
sie funktionieren würde? Wenn ja: ja, tut es :)a, *_ = foo()
wirft alle Werte außer dem ersten weg.Antworten:
Die Verwendung des Unterstrichs für nicht verwendete Variablen ist definitiv akzeptabel. Seien Sie jedoch gewarnt, in einigen Codebasen ist dies keine Option, da dieser Bezeichner als Kurzform für reserviert ist
gettext
. Dies ist der häufigste Einwand gegen diesen Stil (obwohl er, soweit ich das beurteilen kann, für die Mehrheit kein Problem darstellt). Ich würde es immer noch empfehlen und es immer selbst verwenden.Namen wie
dummy
oderunused
neigen dazu, mich persönlich zu irritieren, und ich sehe sie nicht so oft (in Python also - ich kenne eine Delphi-Codebasis, die sichdummy
großzügig nutzt , und sie ist auch in Skripten gelandet, die mit dem fraglichen Programm verknüpft sind). Ich würde dir davon abraten.Es ist auch in Ordnung, nur einen Eintrag aus dem zurückgegebenen Tupel zu extrahieren. Es spart auch Ärger, wenn die Anzahl der nicht verwendeten Werte richtig eingestellt wird. Beachten Sie jedoch, dass es zwei mögliche Nachteile hat:
quelle
Pylint hat es mir zur Gewohnheit gemacht, es so zu machen:
Das heißt, nicht verwendete Ergebnisse haben einen beschreibenden Namen mit dem Präfix _. Pylint betrachtet Einheimische mit dem Präfix _ als nicht verwendet und Globale oder Attribute mit dem Präfix _ als privat.
quelle
Wenn Sie dies in Ihrem gesamten Projekt nur einmal oder sehr selten für die jeweilige Funktion tun, würde ich Variante 1 verwenden, wenn Sie wissen,
gettext
dass in diesem Modul kein Problem vorliegt , und ansonsten Variante 3.Wenn Sie dies häufig tun - und insbesondere, wenn Sie jedes Mal eine andere Teilmenge der Rückgabewerte benötigen (indem Sie einen Wrapper so einstellen, dass nur die zurückgegeben werden, die Sie für unzuverlässig halten), kann es von Vorteil sein, einen Wrapper zu schreiben Dadurch werden die Ergebnisse in ein benanntes Tupel oder in eine Instanz einer anderen beschreibenden Klasse geschrieben, mit der Sie Folgendes ausführen können:
Und dann arbeiten mit
bar.a
,bar.b
undbar.c
.quelle
Wie andere gesagt haben, ist Unterstrich (
_
) der Standard. Wenn jedoch ein Unterstrich für Übersetzungen verwendet wird, ist der doppelte Unterstrich meiner Meinung nach die beste Alternative.var, __, value = "VAR=value".partition('=')
Besser als diese:
var, unused, value = "VAR=value".partition('=')
var, unused_del, value = "VAR=value".partition('=')
var, _del, value = "VAR=value".partition('=')
quelle
Ich bin kein Python-Programmierer, aber für mich ist die dritte Variante am sinnvollsten.
In Variante 3 ist Ihnen absolut klar, mit welchen Werten Sie sich beschäftigen möchten. In Variante 1 und 2 weisen Sie die Werte wieder Variablen zu und können sie somit verwenden. Sie haben sie vielleicht dunkel benannt, aber eine schlechte Benennung ist keine Lösung für ein Problem.
Warum sollten Sie aus Gründen der Übersichtlichkeit einem Steckplatz im Speicher nicht verwendete Werte zuweisen (wie in den Varianten 1 und 2)? Dies wäre eine schlechte Lösung für die Speicherverwaltung.
quelle
Hier ist eine allgemeine Regel: Wenn nur 1 der zurückgegebenen Werte verwendet wird, warum nicht einfach diesen 1-Wert zurückgeben? Wenn das Flag von mehreren Stellen aus aufgerufen wird, behalten Sie ein Flag für den gleichen Wert bei und geben Sie Werte zurück, die dem Flag entsprechen.
BEARBEITEN:
Wäre ich in Ihrer Situation und hätte ich die Funktion nicht geschrieben, würde ich vielleicht Variante 2 wählen. Ich würde die Dummy-Namen dort belassen, damit die Parameter bei Bedarf verwendet werden können. Das Schneiden einer Liste ist mit einem gewissen Aufwand verbunden. Vielleicht können Sie ein paar Bytes sparen, um die unerwünschten Daten zu empfangen.
quelle
%timeit a, _, _ = foo()
vs.%timeit a = foo()[0]
, was 123ns vs. 109ns ergab, dh das Schneiden scheint tatsächlich schneller zu sein als das Auspacken des Wertes. Oder hatten Sie eine bestimmte Situation im Sinn?