876 Stimmen

Stilisierung von mehrzeiligen Bedingungen in 'if'-Anweisungen?

Manchmal breche ich lange Bedingungen in if s auf mehrere Zeilen. Der naheliegendste Weg, dies zu tun, ist:

  if (cond1 == 'val1' and cond2 == 'val2' and
      cond3 == 'val3' and cond4 == 'val4'):
      do_something

Das ist optisch nicht sehr ansprechend, weil die Aktion mit den Bedingungen verschmilzt. Es ist jedoch die natürliche Art und Weise, 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

Aber das ist nicht sehr hübsch :-)

Können Sie einen alternativen Weg empfehlen?

2 Stimmen

Wenn Ihr Editor die Funktion Pep8 Python-Paket, um zu erkennen, wann eine Warnung über PEP8 Verstöße, müssen Sie entweder den E125-Fehler deaktivieren oder eine Formatierungslösung finden, die den Anforderungen der pep8 Kriterien des Pakets. Die Website pep8 des Pakets Ausgabe #126 geht es darum, das Paket strikt an die PEP8-Spezifikation anzupassen. Die Diskussion zu diesem Thema enthält einige Stilvorschläge, die auch hier zu sehen sind.

1 Stimmen

Beachten Sie, dass pep8 für das erste Beispiel "E129 visuell eingerückte Zeile mit gleichem Einzug wie die nächste logische Zeile" ausgibt.

0 Stimmen

Diese Frage ist sehr alt und es gibt eine Menge Meinungen, aber sie ist eindeutig meinungsbasiert. Die Formulierungen "ist nicht sehr ansprechend" und "ist nicht sehr hübsch" legen die Kriterien dafür fest, dass die vermeintlich richtige Antwort diejenige ist, die am besten mit den ästhetischen Vorlieben des Fragestellers übereinstimmt (d. h. eine Meinung). Ich könnte genau dieselbe Frage stellen und behaupten, dass es sich nicht um ein Duplikat handelt, weil mein ästhetischer Geschmack sie als anders qualifiziert und zu einer anderen "richtigen" Antwort führen wird.

1voto

Nader Belal Punkte 147

Entschuldigen Sie meine Unerfahrenheit, aber ich kenne mich mit #Python nicht so gut aus wie jeder von Ihnen hier, aber ich habe etwas Ähnliches beim Skripten meiner eigenen Objekte in einer 3D-BIM-Modellierung gefunden, also werde ich meinen Algorithmus an den von Python anpassen.

Das Problem, das ich hier sehe, ist ein doppelseitiges:

  1. Für jemanden, der versucht, die Schrift zu entziffern, mögen die Werte fremd erscheinen.
  2. Die Wartung des Codes wird mit hohen Kosten verbunden sein, wenn diese Werte geändert werden (höchstwahrscheinlich) oder wenn neue Bedingungen hinzugefügt werden müssen (defektes Schema).

Um all diese Probleme zu umgehen, muss Ihr Skript folgendermaßen aussehen

param_Val01 = Value 01   #give a meaningful name for param_Val(i) preferable an integer
param_Val02 = Value 02
param_Val03 = Value 03
param_Val04 = Value 04   # and ... etc

conditions = 0           # this is a value placeholder

########
Add script that if true will make:

conditions = conditions + param_Val01   #value of placeholder is updated
########

### repeat as needed

if conditions = param_Val01 + param_Val02 + param_Val03 + param_Val04:
    do something

Vorteile dieser Methode:

  1. Die Schrift ist lesbar.

  2. Das Skript kann leicht gewartet werden.

  3. Bedingungen ist eine 1-Vergleichsoperation mit einer Summe von Werten, die die gewünschten Bedingungen darstellen.

  4. Keine Notwendigkeit für mehrstufige Bedingungen

Ich hoffe, es hilft euch allen

1voto

SarcasticSully Punkte 442

Sie könnten es in zwei Zeilen aufteilen

total = cond1 == 'val' and cond2 == 'val2' and cond3 == 'val3' and cond4 == val4
if total:
    do_something()

Oder fügen Sie sogar eine Bedingung nach der anderen hinzu. Auf diese Weise trennt man zumindest das Durcheinander vom if .

1voto

El Ninja Trepador Punkte 915

Ich habe mich auch schwer getan, eine vernünftige Lösung dafür zu finden, also habe ich mir etwas einfallen lassen (kein Patentrezept, denn das ist vor allem eine Frage des Geschmacks).

if bool(condition1 and
        condition2 and
        ...
        conditionN):
    foo()
    bar()

Ich finde, dass diese Lösung im Vergleich zu anderen, die ich gesehen habe, einige Vorteile hat, nämlich genau 4 Leerzeichen mehr an Einrückung (bool), so dass alle Bedingungen vertikal aufgereiht werden können, und der Hauptteil der if-Anweisung kann auf eine klare Art und Weise eingerückt werden. Damit bleiben auch die Vorteile der Kurzschlussauswertung von booleschen Operatoren erhalten, aber natürlich kommt der Overhead eines Funktionsaufrufs hinzu, der im Grunde nichts tut. Man könnte (berechtigterweise) 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 es ist letztlich eine Frage des Geschmacks.

Als ich dies schrieb und über das "Problem" nachdachte, kam mir lustigerweise Folgendes in den Sinn noch eine Idee, die den Overhead eines Funktionsaufrufs beseitigt. Warum sollte man nicht durch zusätzliche Klammerpaare anzeigen, dass man im Begriff ist, eine komplexe Bedingung einzugeben? Sagen wir, 2 mehr, um einen schönen 2-Leerzeichen-Einzug der Unterbedingungen relativ zum Körper der if-Anweisung zu erhalten. Beispiel:

if (((foo and
      bar and
      frob and
      ninja_bear))):
    do_stuff()

Das gefällt mir irgendwie, denn wenn man sich das ansieht, klingelt es sofort im Kopf. "Hey, das ist eine komplexe Sache, die hier vor sich geht!" . Ja, ich weiß, dass Klammern der Lesbarkeit nicht förderlich sind, aber diese Bedingungen sollten selten genug auftauchen, und wenn sie auftauchen, müssen Sie sowieso innehalten und sie sorgfältig lesen (denn sie sind komplex ).

Wie auch immer, nur zwei weitere Vorschläge, die ich hier noch nicht gesehen habe. Hoffentlich hilft das jemandem :)

1voto

Jason Baker Punkte 180981

Der Vollständigkeit halber noch ein paar andere zufällige Ideen. Wenn sie für Sie funktionieren, verwenden Sie sie. Andernfalls sind Sie wahrscheinlich besser dran, wenn Sie etwas anderes versuchen.

Sie könnten dies auch mit einem Wörterbuch tun:

>>> x = {'cond1' : 'val1', 'cond2' : 'val2'}
>>> y = {'cond1' : 'val1', 'cond2' : 'val2'}
>>> x == y
True

Diese Option ist etwas komplizierter, aber vielleicht ist sie auch für Sie nützlich:

class Klass(object):
    def __init__(self, some_vars):
        #initialize conditions here
    def __nonzero__(self):
        return (self.cond1 == 'val1' and self.cond2 == 'val2' and
                self.cond3 == 'val3' and self.cond4 == 'val4')

foo = Klass()
if foo:
    print "foo is true!"
else:
    print "foo is false!"

Ich weiß nicht, ob das für Sie in Frage kommt, aber es ist eine weitere Option, die Sie in Betracht ziehen sollten. Hier ist eine weitere Möglichkeit:

class Klass(object):
    def __init__(self):
        #initialize conditions here
    def __eq__(self):
        return (self.cond1 == 'val1' and self.cond2 == 'val2' and
               self.cond3 == 'val3' and self.cond4 == 'val4')

x = Klass(some_values)
y = Klass(some_other_values)
if x == y:
    print 'x == y'
else:
    print 'x!=y'

Die letzten beiden habe ich nicht getestet, aber die Konzepte sollten ausreichen, um Sie auf den Weg zu bringen, wenn Sie sich für diese Methode entscheiden.

(Und für das Protokoll, wenn dies nur eine einmalige Sache ist, sind Sie wahrscheinlich besser dran, wenn Sie die Methode verwenden, die Sie zu Beginn vorgestellt haben. Wenn Sie den Vergleich an vielen Stellen durchführen, können diese Methoden die Lesbarkeit so weit verbessern, dass Sie sich nicht so schlecht fühlen, weil sie etwas hakelig sind).

0voto

Artur Gaspar Punkte 4287

Ich verwende normalerweise:

if ((cond1 == 'val1' and cond2 == 'val2' and
     cond3 == 'val3' and cond4 == 'val4')):
    do_something()

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X