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.

28voto

krawyoti Punkte 18921

Hier ist meine ganz persönliche Meinung: Lange Bedingungen sind (meiner Meinung nach) ein Codegeruch, der eine Umstrukturierung in eine boolesche Funktion/Methode nahelegt. Zum Beispiel:

def is_action__required(...):
    return (cond1 == 'val1' and cond2 == 'val2'
            and cond3 == 'val3' and cond4 == 'val4')

Wenn ich nun einen Weg finden würde, mehrzeilige Bedingungen gut aussehen zu lassen, würde ich mich wahrscheinlich damit zufrieden geben und die Überarbeitung überspringen.

Andererseits ist es ein Anreiz für die Überarbeitung, wenn sie mein ästhetisches Empfinden stören.

Meine Schlussfolgerung ist daher, dass Bedingungen mit mehreren Linien hässlich aussehen sollten und dies ein Anreiz ist, sie zu vermeiden.

19voto

DzinX Punkte 51124

Ich schlage vor, die and Schlüsselwort in die zweite Zeile zu verschieben und alle Zeilen, die Bedingungen enthalten, mit zwei statt vier Leerzeichen einzurücken:

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

Genau so löse ich dieses Problem in meinem Code. Ein Schlüsselwort als erstes Wort in der Zeile macht die Bedingung viel lesbarer, und durch die Verringerung der Anzahl der Leerzeichen wird die Bedingung von der Aktion weiter unterschieden.

18voto

Mark Amery Punkte 124946

Es scheint sich zu lohnen, ihn zu zitieren PEP 0008 (Pythons offizieller Stil-Leitfaden), da er sich zu diesem Thema recht ausführlich äußert:

Wenn der bedingte Teil einer if -Anweisung so lang ist, dass sie über mehrere Zeilen geschrieben werden muss, ist es erwähnenswert, dass die Kombination eines zweistelligen Schlüsselworts (d. h. if ), plus ein einzelnes Leerzeichen, plus eine öffnende Klammer erzeugt einen natürlichen Einzug von 4 Leerzeichen für die nachfolgenden Zeilen der mehrzeiligen Bedingung. Dies kann zu einem visuellen Konflikt mit der eingerückten Codefolge führen, die innerhalb der if -Anweisung, die natürlich auch auf 4 Leerzeichen eingerückt werden würde. Dieses PEP nimmt nicht explizit Stellung dazu, wie (oder ob) man solche bedingten Zeilen von der verschachtelten Suite innerhalb der if -Anweisung. Zulässige Optionen in dieser Situation sind unter anderem:

# No extra indentation.
if (this_is_one_thing and
    that_is_another_thing):
    do_something()

# Add a comment, which will provide some distinction in editors
# supporting syntax highlighting.
if (this_is_one_thing and
    that_is_another_thing):
    # Since both conditions are true, we can frobnicate.
    do_something()

# Add some extra indentation on the conditional continuation line.
if (this_is_one_thing
        and that_is_another_thing):
    do_something()

Beachten Sie das "nicht beschränkt auf" im obigen Zitat; neben den im Style Guide vorgeschlagenen Ansätzen sind auch einige der in anderen Antworten auf diese Frage vorgeschlagenen akzeptabel.

8voto

zkanda Punkte 644

Hier ist, was ich tun, denken Sie daran, dass "all" und "any" akzeptiert eine iterable, so dass ich nur eine lange Bedingung in einer Liste und lassen "all" die Arbeit tun.

condition = [cond1 == 'val1', cond2 == 'val2', cond3 == 'val3', cond4 == 'val4']

if all(condition):
   do_something

6voto

rgenito Punkte 1691

Ich persönlich mag es, langen if-Anweisungen einen Sinn zu geben. Ich müsste den Code durchsuchen, um ein passendes Beispiel zu finden, aber hier ist das erste Beispiel, das mir einfällt: Nehmen wir an, ich stoße auf eine eigenartige Logik, bei der ich eine bestimmte Seite in Abhängigkeit von vielen Variablen anzeigen möchte.

Englisch: "Wenn der eingeloggte Benutzer KEIN Administrator ist, sondern nur ein normaler Lehrer und selbst kein Schüler ist..."

if not user.isAdmin() and user.isTeacher() and not user.isStudent():
    doSomething()

Das mag zwar gut aussehen, aber das Lesen dieser if-Anweisungen ist eine Menge Arbeit. Wie wäre es, wenn wir die Logik einem Label zuordnen, das Sinn macht. Das "Label" ist eigentlich der Name der Variablen:

displayTeacherPanel = not user.isAdmin() and user.isTeacher() and not user.isStudent()
if displayTeacherPanel:
    showTeacherPanel()

Das mag albern klingen, aber Sie könnten eine weitere Bedingung haben, bei der Sie ein anderes Element NUR dann anzeigen möchten, wenn Sie das Lehrerpanel anzeigen ODER wenn der Benutzer standardmäßig Zugriff auf dieses andere spezifische Panel hat:

if displayTeacherPanel or user.canSeeSpecialPanel():
    showSpecialPanel()

Wenn Sie versuchen, die obige Bedingung zu schreiben, ohne Variablen zum Speichern und Kennzeichnen Ihrer Logik zu verwenden, erhalten Sie nicht nur eine sehr unübersichtliche, schwer lesbare logische Aussage, sondern Sie wiederholen sich auch. Es gibt zwar begründete Ausnahmen, aber denken Sie daran: Wiederholen Sie sich nicht (DRY).

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