webentwicklung-frage-antwort-db.com.de

Codestil zum Einrücken von mehrzeiligen 'if'-Anweisungen?

Wenn Sie lange if-Bedingungen einrücken, machen Sie normalerweise so etwas (PyDev rückt tatsächlich so ein):

if (collResv.repeatability is None or
    collResv.somethingElse):
    collResv.rejected = True
    collResv.rejectCompletely()

Dies setzt jedoch den Block, der durch die if-Anweisung gestartet wird, auf dieselbe Einrückungsstufe wie den letzten Teil der if-Bedingung, was es meiner Meinung nach sehr hässlich/schwer macht, zu lesen, da Sie nicht sofort sehen, wo der Block beginnt.

Einige andere Stile, über die ich nachgedacht habe:

if (collResv.repeatability is None or
        collResv.somethingElse):
    collResv.rejected = True
    collResv.rejectCompletely()

Dies sieht ziemlich inkonsistent aus, da die zweite Zeile viel stärker eingerückt ist als die erste, aber lesbar.

if (collResv.repeatability is None or
  collResv.somethingElse):
    collResv.rejected = True
    collResv.rejectCompletely()

Dies ist auch lesbarer als das erste Beispiel, aber der Einzug ist kein Vielfaches von 4 mehr und außerdem sieht es falsch aus, da die zweite Zeile weniger Einzug als der Beginn der Bedingung in der ersten Zeile hat.


Meine Hauptfrage lautet also: Gibt es einen vorgeschlagenen Einrückungsstil für Fälle wie diesen, die keine überlangen Zeilen erfordern (d. H. Eine einzeilige Bedingung)? Wenn nicht, was bevorzugen Sie für solche Fälle?

33
ThiefMaster

Dies ist eine indirekte Antwort - nicht die direkte Beantwortung der Stilfrage, aber es ist die praktische Antwort im Allgemeinen, also ist es erwähnenswert.

Ich finde es äußerst selten, mehrzeilige Bedingungen zu schreiben. Hierfür gibt es zwei Faktoren:

  • Code nicht in 80 Spalten umbrechen. Der Rat von PEP-8 zu diesem Thema ist uralt und schädlich. Wir haben die Zeiten von 80x25 Terminals und Editoren hinter uns, die mit dem Umwickeln nicht vernünftig umgehen können. 100 Spalten sind in Ordnung und 120 sind in der Regel auch akzeptabel.
  • Wenn die Bedingungen so lang werden, dass sie noch umgebrochen werden müssen, ist es normalerweise sinnvoll, einen Teil der Logik aus dem Bedingten heraus in einen separaten Ausdruck zu verschieben. Dies hilft auch, die Lesbarkeit zu verbessern.

Um meine letzten Projekte herumzuschneiden, um 12kloc herum, gibt es nur eine Bedingung, die lang genug war, damit sie verpackt werden konnte. Das Problem tritt einfach sehr selten auf. Wenn Sie dies tun müssen, rücken Sie sie, wie nosklo sagt, separat ein - wie Sie bemerkt haben, ist das Einrücken auf dieselbe Ebene wie der Block darunter verwirrend und schwer zu lesen.

9
Glenn Maynard

Oft gehe ich dieses Problem um, indem ich die Bedingung in einer eigenen Anweisung berechnet:

condition = (collResv.repeatability is None or
             collResv.somethingElse)
if condition:
    collResv.rejected = True
    collResv.rejectCompletely()

Für eine immer noch relativ kurze Bedingung, wie in Ihrem spezifischen Beispiel, würde ich für die Lösung von nosklo gehen - die hier verwendete zusätzliche Anweisung eignet sich eher für noch längere bedingte Ausdrücke.

21
Oben Sonne

Das ist was ich mache:

if (collResv.repeatability is None or
        collResv.somethingElse):
    collResv.rejected = True
    collResv.rejectCompletely()
13
nosklo

Ein Problem bei allen vorherigen Vorschlägen besteht darin, dass die logischen Operatoren für die Folgebedingungen in der vorhergehenden Zeile stehen. Imo, das macht es weniger lesbar.

Ich empfehle, den logischen Operator in dieselbe Zeile zu setzen wie die Bedingung, die er an die if-Anweisung anfügt.

Das ist meiner Meinung nach besser

if (None == foo
        and None == bar
        or None == foo_bar):

als das:

if (None == foo and
        None == bar or
        None == foo_bar):
10
Reimund

PEP-8 scheint hier tatsächlich widersprüchlich. Während das Beispiel unter "Maximale Leitungslänge" die Verwendung von Klammern und eines Standardeinzugs von 4 Zeichen zeigt, sagt der Abschnitt "Einzug" in Bezug auf Funktionsdeklarationen. Weitere Einrückungen sollten verwendet werden, um sich klar als Fortsetzungszeile zu unterscheiden. ". Ich kann nicht verstehen, warum dies nur auf "def" und nicht auf "wenn" beschränkt wäre.

3
mcote

Ich würde es so machen. Behalten Sie es weit entfernt, um nicht verwirrt zu werden.

if (collResv.repeatability is None or
                          collResv.somethingElse):
    collResv.rejected = True
    collResv.rejectCompletely()

PEP-8-Beratung ist hier richtig.

http://www.python.org/dev/peps/pep-0008/#indentation

Der folgende Code wird empfohlen

# Aligned with opening delimiter
foo = long_function_name(var_one, var_two,
                         var_three, var_four)

# More indentation included to distinguish this from the rest.
def long_function_name(
        var_one, var_two, var_three,
        var_four):
    print(var_one)

Der folgende Code wird nicht empfohlen

# Arguments on first line forbidden when not using vertical alignment
foo = long_function_name(var_one, var_two,
    var_three, var_four)

# Further indentation required as indentation is not distinguishable
def long_function_name(
    var_one, var_two, var_three,
    var_four):
    print(var_one)
2
ronak

In einem solchen Fall würde ich einfach Folgendes tun:

if (collResv.repeatability is None or
    collResv.somethingElse):
    # do:
    collResv.rejected = True
    collResv.rejectCompletely()
0
eyquem

Pep-8 empfiehlt, wie Sie Ihr ursprüngliches Beispiel eingerückt haben.

Wenn Sie nun bereit sind, dem ach so heiligen Stilführer zu entfliehen :-), könnten Sie den Operator in die nächste Zeile verschieben:

if (collResv.repeatability is None
    or collResv.somethingElse):
    collResv.rejected = True
    collResv.rejectCompletely()

Ich bin nicht wirklich ein Fan davon, ich finde Ihre ursprüngliche Syntax ziemlich einfach zu lesen und würde nicht viel Zeit mit dem Einzug oder den Zeilenumbrüchen verbringen.

0
stderr