Manchmal breche ich lange Bedingungen in if
s in mehrere Zeilen. Der naheliegendste Weg, dies zu tun, ist:
if (cond1 == 'val1' and cond2 == 'val2' and
cond3 == 'val3' and cond4 == 'val4'):
do_something
Ist optisch nicht sehr sehr ansprechend, da sich die Aktion mit den Bedingungen verbindet. Es ist jedoch der natürliche Weg, die korrekte Python-Einrückung von 4 Leerzeichen zu verwenden.
Im Moment benutze ich:
if ( cond1 == 'val1' and cond2 == 'val2' and
cond3 == 'val3' and cond4 == 'val4'):
do_something
Das ist aber nicht sehr hübsch. :-)
Können Sie einen alternativen Weg empfehlen?
python
coding-style
if-statement
Eli Bendersky
quelle
quelle
pep8
Kriterien des Pakets erfüllt. Inpep8
der Ausgabe Nr. 126 des Pakets geht es darum, das Paket so zu reparieren, dass es genau der PEP8-Spezifikation entspricht. Die Diskussion für das Problem enthält einige Stilvorschläge, die auch hier zu sehen sind.Antworten:
Sie müssen in Ihrer zweiten bedingten Zeile keine 4 Leerzeichen verwenden. Vielleicht verwenden:
Vergessen Sie auch nicht, dass das Leerzeichen flexibler ist, als Sie vielleicht denken:
Beide sind allerdings ziemlich hässlich.
Vielleicht die Klammern verlieren (der Style Guide rät jedoch davon ab)?
Dies gibt Ihnen zumindest eine gewisse Differenzierung.
Oder auch:
Ich glaube ich bevorzuge:
Hier ist der Style Guide , der (seit 2010) die Verwendung von Klammern empfiehlt.
quelle
and
und zu brechenif
.Ich habe in dem entarteten Fall, in dem es einfach UND und ODER sind, auf Folgendes zurückgegriffen.
Es rasiert einige Zeichen und macht deutlich, dass die Bedingung nicht subtil ist.
quelle
if destroy_world and DestroyTheWorld() == world_is_destroyed: ...
. Großartig, jetzt hast du die Welt durch einen Unfall zerstört. WIE KONNTEST DU?Jemand muss sich hier für die Verwendung vertikaler Leerzeichen einsetzen! :) :)
Dies macht jeden Zustand deutlich sichtbar. Es ermöglicht auch eine sauberere Expression komplexerer Bedingungen:
Ja, wir tauschen aus Gründen der Klarheit ein bisschen vertikale Immobilien aus. Lohnt sich IMO.
quelle
and
B. sowieor
) nach dem Operator und nicht davor liegt.PEP8
der Fall, sondern erschwert auch die Bestimmung der Logikoperation, mit der Sie verketten. Ich würde dies durchfallen lassen, wenn es durch Codeüberprüfung an meinen Schreibtisch käme.Ich bevorzuge diesen Stil, wenn ich einen schrecklich großen If-Zustand habe:
quelle
and
undor
Operatoren am Anfang der Zeile gegen PEP 0008 verstoßen , in dem es heißt: "Der bevorzugte Ort, um einen binären Operator zu umgehen , ist nach dem Operator, nicht davor." . Ich mag es jedoch, wenn die schließende Klammer und der Doppelpunkt in einer eigenen Zeile stehen, um die if-Bedingung vom Körper zu trennen (und dies ist durchaus möglich, während Ihre booleschen Operatoren für die Einhaltung von PEP-0008 am Ende der Zeile bleiben).For decades the recommended style was to break after binary operators. But this can hurt readability in two ways
...In Python code, it is permissible to break before or after a binary operator, as long as the convention is consistent locally. For new code Knuth's style is suggested.
(Knuths Stil ist es, die Linie mit dem Operator zu beginnen).Hier ist meine ganz persönliche Einstellung: Lange Bedingungen sind (meiner Ansicht nach) ein Codegeruch, der darauf hindeutet, in eine boolesche Rückgabefunktion / -methode umzuwandeln. Zum Beispiel:
Wenn ich nun einen Weg finden würde, mehrzeilige Bedingungen gut aussehen zu lassen, würde ich mich wahrscheinlich damit zufrieden geben, sie zu haben, und das Refactoring überspringen.
Andererseits wirkt es ein Anreiz für das Refactoring, wenn sie meinen ästhetischen Sinn stören.
Mein Fazit ist daher, dass Mehrleitungsbedingungen hässlich aussehen sollten und dies ein Anreiz ist, sie zu vermeiden.
quelle
Das verbessert sich nicht so sehr, aber ...
quelle
Ich schlage vor, das
and
Schlüsselwort in die zweite Zeile zu verschieben und alle Zeilen mit Bedingungen mit zwei statt vier Leerzeichen einzurücken:Genau so löse ich dieses Problem in meinem Code. Wenn Sie ein Schlüsselwort als erstes Wort in der Zeile haben, ist die Bedingung viel besser lesbar, und durch Verringern der Anzahl der Leerzeichen wird die Bedingung weiter von der Aktion unterschieden.
quelle
Es scheint sich zu lohnen, PEP 0008 (Pythons offizieller Styleguide) zu zitieren , da es dieses Problem in bescheidener Länge kommentiert:
Beachten Sie das "nicht beschränkt auf" im obigen Zitat; Neben den im Styleguide vorgeschlagenen Ansätzen sind auch einige der in anderen Antworten auf diese Frage vorgeschlagenen Ansätze akzeptabel.
quelle
Ich mache Folgendes: Denken Sie daran, dass "alle" und "alle" eine Iterierbarkeit akzeptieren. Ich habe also einfach eine lange Bedingung in eine Liste aufgenommen und "alle" die Arbeit machen lassen.
quelle
Ich bin überrascht, meine bevorzugte Lösung nicht zu sehen.
Da
and
es sich um ein Schlüsselwort handelt, wird es von meinem Editor hervorgehoben und unterscheidet sich ausreichend von do_something darunter.quelle
Hinzu kommt, was @krawyoti gesagt hat ... Lange Bedingungen riechen, weil sie schwer zu lesen und schwer zu verstehen sind. Die Verwendung einer Funktion oder einer Variablen macht den Code klarer. In Python bevorzuge ich es, vertikalen Raum zu verwenden, Klammern einzuschließen und die logischen Operatoren am Anfang jeder Zeile zu platzieren, damit die Ausdrücke nicht wie "schwebend" aussehen.
Wenn die Bedingungen wie in einer
while
Schleife mehrmals ausgewertet werden müssen , ist die Verwendung einer lokalen Funktion am besten.quelle
Persönlich mag ich es, langen if-Aussagen Bedeutung zu verleihen. Ich müsste den Code durchsuchen, um ein geeignetes Beispiel zu finden, aber hier ist das erste Beispiel, das mir in den Sinn kommt: Nehmen wir an, ich stoße zufällig auf eine skurrile Logik, bei der ich abhängig von vielen Variablen eine bestimmte Seite anzeigen möchte.
Englisch: "Wenn der angemeldete Benutzer KEIN Administratorlehrer ist, sondern nur ein regulärer Lehrer und selbst kein Schüler ..."
Sicher, das mag gut aussehen, aber das Lesen dieser if-Anweisungen ist eine Menge Arbeit. Wie wäre es, wenn wir die Logik dem Etikett zuweisen, das Sinn macht? Das "Label" ist eigentlich der Variablenname:
Dies mag albern erscheinen, aber Sie haben möglicherweise noch eine andere Bedingung, bei der Sie NUR dann ein anderes Element anzeigen möchten, wenn und nur wenn Sie das Lehrerfenster anzeigen ODER wenn der Benutzer standardmäßig Zugriff auf dieses andere spezifische Feld hat:
Versuchen Sie, die obige Bedingung zu schreiben, ohne Variablen zum Speichern und Beschriften Ihrer Logik zu verwenden, und Sie erhalten nicht nur eine sehr unordentliche, schwer lesbare logische Anweisung, sondern Sie haben sich auch nur wiederholt. Denken Sie daran, auch wenn es vernünftige Ausnahmen gibt: Wiederholen Sie sich nicht (DRY).
quelle
"all" und "any" sind nett für die vielen Bedingungen des gleichen Falltyps. ABER sie bewerten immer alle Bedingungen. Wie in diesem Beispiel gezeigt:
quelle
all()
dahin in einer Liste enthalten sindf()
, werden sie alle ausgewertet , es sei denn, Sie wickeln sie jeweils in ein Lambda ein und verwenden Ihren Trick. Mit anderen Worten, Aaron: Ich denke, Anders hat versucht, über Bedingungen im Allgemeinen zu sprechen, wobei Callables als spezifisches Beispiel verwendet wurden. Ihre Gegenerwiderung gilt jedoch nur für Funktionen.(Ich habe die Bezeichner leicht geändert, da Namen mit fester Breite nicht für echten Code repräsentativ sind - zumindest nicht für echten Code, auf den ich stoße - und die Lesbarkeit eines Beispiels glauben.)
Dies funktioniert gut für "und" und "oder" (es ist wichtig, dass sie zuerst in der zweiten Zeile stehen), aber viel weniger für andere lange Bedingungen. Glücklicherweise scheint Ersteres der häufigere Fall zu sein, während Letzteres häufig leicht mit einer temporären Variablen umgeschrieben werden kann. (Es ist normalerweise nicht schwer, aber es kann schwierig oder viel weniger offensichtlich / lesbar sein, den Kurzschluss von "und" / "oder" beim Umschreiben beizubehalten.)
Da ich diese Frage in Ihrem Blogbeitrag zu C ++ gefunden habe , werde ich angeben, dass mein C ++ - Stil identisch ist:
quelle
Schlicht und einfach, besteht auch pep8-Prüfungen:
In letzter Zeit habe ich die
all
undany
-Funktionen bevorzugt , da ich And and Or-Vergleiche selten mische. Dies funktioniert gut und hat den zusätzlichen Vorteil, dass ich mit dem Verständnis der Generatoren früh versage:Denken Sie daran, eine einzige iterable zu übergeben! Die Übergabe von N-Argumenten ist nicht korrekt.
Hinweis:
any
ist wie vieleor
Vergleiche,all
ist wie vieleand
Vergleiche.Dies lässt sich gut mit dem Verständnis des Generators kombinieren, zum Beispiel:
Mehr zum Generatorverständnis
quelle
Was ist, wenn wir nur eine zusätzliche Leerzeile zwischen dem Zustand und dem Körper einfügen und den Rest auf kanonische Weise erledigen?
ps Ich benutze immer Tabulatoren, keine Leerzeichen; Ich kann nicht fein einstellen ...
quelle
and
undor
in der nächsten Zeile beginnen solltenWas ich normalerweise mache ist:
Auf diese Weise markieren die schließende Klammer und der Doppelpunkt visuell das Ende unseres Zustands.
quelle
and
oder zu brechenor
.Alle Befragten, die auch Multi-Bedingungen für die if-Anweisung bereitstellen, sind genauso hässlich wie das vorgestellte Problem. Sie lösen dieses Problem nicht, indem Sie dasselbe tun.
Sogar die Antwort von PEP 0008 ist abstoßend.
Hier ist ein weitaus besser lesbarer Ansatz
Soll ich meine Worte essen? Überzeugen Sie mich, dass Sie mehrere Bedingungen benötigen, und ich werde diese buchstäblich ausdrucken und zu Ihrer Unterhaltung essen.
quelle
Ich denke, die Lösung von @ zkanda wäre gut mit einer kleinen Wendung. Wenn Sie Ihre Bedingungen und Werte in ihren jeweiligen Listen hätten, könnten Sie ein Listenverständnis verwenden, um den Vergleich durchzuführen, was die Dinge für das Hinzufügen von Bedingungs- / Wertepaaren etwas allgemeiner machen würde.
Wenn ich eine solche Aussage fest codieren wollte, würde ich sie aus Gründen der Lesbarkeit folgendermaßen schreiben:
Und nur um eine andere Lösung mit einem
iand
Bediener herauszubringen :quelle
all(map(eq, have, expected))
. (mitfrom operator import eq
)Nur ein paar andere zufällige Ideen der Vollständigkeit halber. Wenn sie für Sie arbeiten, verwenden Sie sie. Ansonsten ist es wahrscheinlich besser, wenn Sie etwas anderes ausprobieren.
Sie können dies auch mit einem Wörterbuch tun:
Diese Option ist komplizierter, kann aber auch nützlich sein:
Keine Ahnung, ob das für Sie funktioniert, aber es ist eine weitere Option, die Sie in Betracht ziehen sollten. Hier ist noch ein Weg:
Die letzten beiden habe ich nicht getestet, aber die Konzepte sollten ausreichen, um Sie zum Laufen zu bringen, wenn Sie das möchten.
(Und fürs Protokoll: Wenn dies nur eine einmalige Sache ist, ist es wahrscheinlich besser, die Methode zu verwenden, die Sie zuerst vorgestellt haben. Wenn Sie den Vergleich an vielen Stellen durchführen, können diese Methoden die Lesbarkeit ausreichend verbessern, um sie durchzuführen du fühlst dich nicht so schlecht wegen der Tatsache, dass sie irgendwie hackig sind.)
quelle
Ich habe mich bemüht, auch hier einen vernünftigen Weg zu finden, also bin ich auf eine Idee gekommen (keine Silberkugel, da dies hauptsächlich Geschmackssache ist).
Ich finde ein paar Vorteile in dieser Lösung im Vergleich zu anderen, die ich gesehen habe, nämlich, dass Sie genau 4 zusätzliche Einrückungsräume (bool) erhalten, sodass alle Bedingungen vertikal ausgerichtet werden können und der Hauptteil der if-Anweisung eingerückt werden kann ein klarer (ish) Weg. Dies behält auch die Vorteile der Kurzschlussauswertung von Booleschen Operatoren bei, erhöht aber natürlich den Overhead eines Funktionsaufrufs, der im Grunde nichts bewirkt. Sie könnten (gültig) argumentieren, dass jede Funktion, die ihr Argument zurückgibt, hier anstelle von bool verwendet werden könnte, aber wie gesagt, es ist nur eine Idee und letztendlich eine Frage des Geschmacks.
Komischerweise kam mir beim Schreiben und Nachdenken über das "Problem" eine weitere Idee, mit der der Aufwand für einen Funktionsaufruf entfällt. Warum nicht angeben, dass wir mit zusätzlichen Klammerpaaren in eine komplexe Bedingung eintreten werden? Sagen Sie 2 weitere, um einen schönen 2-Leerzeichen-Einzug der Unterbedingungen relativ zum Hauptteil der if-Anweisung zu erhalten. Beispiel:
Ich mag das irgendwie, denn wenn du es dir ansiehst, läutet sofort eine Glocke in deinem Kopf und sagt: "Hey, hier ist eine komplexe Sache los!" . Ja, ich weiß, dass Klammern die Lesbarkeit nicht verbessern, aber diese Bedingungen sollten selten genug auftreten. Wenn sie angezeigt werden, müssen Sie sie trotzdem vorsichtig lesen (weil sie komplex sind ).
Wie auch immer, nur zwei weitere Vorschläge, die ich hier nicht gesehen habe. Hoffe das hilft jemandem :)
quelle
Sie können es in zwei Zeilen aufteilen
Oder fügen Sie sogar jeweils eine Bedingung hinzu. Auf diese Weise trennt es zumindest die Unordnung von der
if
.quelle
Ich weiß, dass dieser Thread alt ist, aber ich habe Python 2.7-Code und PyCharm (4.5) beschwert sich immer noch über diesen Fall:
Selbst mit der PEP8-Warnung "visuell eingerückte Zeile mit demselben Einzug wie die nächste logische Zeile" ist der tatsächliche Code vollständig in Ordnung? Es ist nicht "Einrückung?"
... es gibt Zeiten, in denen ich mir wünschte, Python hätte die Kugel gebissen und wäre nur mit geschweiften Klammern gegangen. Ich frage mich, wie viele Fehler im Laufe der Jahre aufgrund versehentlicher falscher Einrückungen versehentlich eingeführt wurden ...
quelle
Packen Sie Ihre Bedingungen in eine Liste und machen Sie dann etwas. mögen:
quelle
Ich finde, wenn ich lange Bedingungen habe, habe ich oft einen kurzen Code-Körper. In diesem Fall rücke ich den Körper nur doppelt ein, also:
quelle
oder wenn dies klarer ist:
Es gibt keinen Grund, warum der Einzug in diesem Fall ein Vielfaches von 4 sein sollte, z. B. "Ausgerichtet am öffnenden Trennzeichen":
http://google-styleguide.googlecode.com/svn/trunk/pyguide.html?showone=Indentation#Indentation
quelle
Hier ist ein anderer Ansatz:
Dies macht es auch einfach, eine weitere Bedingung hinzuzufügen, ohne die if-Anweisung zu ändern, indem einfach eine andere Bedingung an die Liste angehängt wird:
quelle
Ich benutze normalerweise:
quelle
Wenn unsere if & an else-Bedingung mehrere Anweisungen ausführen muss, können wir wie unten schreiben. Jedes Mal, wenn wir ein anderes Beispiel mit einer Aussage darin haben.
Danke, es funktioniert für mich.
quelle
Verzeihen Sie meine Noobness, aber es kommt vor, dass ich #Python nicht so gut kenne wie jeder von Ihnen hier, aber es kommt vor, dass ich etwas Ähnliches gefunden habe, als ich meine eigenen Objekte in einer 3D-BIM-Modellierung geschrieben habe, also werde ich meinen Algorithmus anpassen das von Python.
Das Problem, das ich hier finde, ist doppelseitig:
Um all diese Probleme zu umgehen, muss Ihr Skript so aussehen
Vorteile dieser Methode:
Skript ist lesbar.
Das Skript kann einfach gepflegt werden.
Hoffe es hilft euch allen
quelle