web-dev-qa-db-fra.com

Style de code pour l'indentation de l'instruction 'if' multiligne?

Lorsque vous indentez longtemps dans des conditions, vous faites habituellement quelque chose comme ceci (en fait, les indentations de PyDev comme ça):

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

Cependant, cela place le bloc commencé par l'instruction if sur le même niveau d'indentation que la dernière partie de la condition if, ce qui le rend très moche/difficile à lire à mon avis car vous ne voyez pas immédiatement où le bloc commence.

Quelques autres styles auxquels j'ai pensé:

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

Cela semble assez incohérent car la deuxième ligne est indentée beaucoup plus que la première ligne mais elle est lisible.

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

C’est aussi plus lisible que le premier exemple, mais l’indentation n’est plus un multiple de 4 et en plus elle a l’air fausse, car la deuxième ligne a moins d’indentation que le début de la condition de la première ligne.


Ma question principale est donc la suivante: existe-t-il un style d'indentation suggéré pour les cas tels que ceux ne nécessitant pas de lignes trop longues (c'est-à-dire une condition de ligne unique)? Si non, que préférez-vous vous pour de tels cas?

33
ThiefMaster

Il s’agit d’une réponse indirecte - ne répondant pas directement à la question sur le style, mais c’est la réponse pratique en général, c’est donc utile de le mentionner.

Je trouve extrêmement rare de devoir écrire des conditionnels multilignes. Il y a deux facteurs à cela:

  • Ne pas envelopper le code à 80 colonnes. Le conseil de PEP-8 à ce sujet est ancien et nuisible; Nous avons bien dépassé l'époque des terminaux 80x25 et des éditeurs qui ne peuvent pas gérer intelligemment l'emballage. 100 colonnes, c'est bien, et 120 est généralement acceptable.
  • Si les conditions deviennent si longues qu'elles doivent encore être bouclées, il est généralement raisonnable de déplacer une partie de la logique du conditionnel vers une expression distincte. Cela tend également à améliorer la lisibilité.

En parcourant mes récents projets, autour de 12kloc, il n’ya qu’un conditionnel suffisamment long pour le conditionner; la question se pose simplement très rarement. Si vous avez besoin de le faire, alors, comme le dit nosklo, indentez-le séparément - comme vous l'avez remarqué, l'indenter au même niveau que le bloc en dessous est confus et difficile à lire.

9
Glenn Maynard

Souvent, je contourne ce problème en calculant la condition dans une déclaration personnelle:

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

Bien que, pour une condition encore relativement courte comme dans votre exemple spécifique, je choisirais la solution de nosklo - l'instruction supplémentaire utilisée ici convient mieux aux expressions conditionnelles encore plus longues.

21
Oben Sonne

C'est ce que je fais:

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

Un problème avec toutes les suggestions précédentes est que les opérateurs logiques des conditions suivantes sont placés sur la ligne précédente. Imo, ça le rend moins lisible.

Je recommande de placer l'opérateur logique sur la même ligne que la condition qu'il ajoute à l'instruction if.

Ceci à mon avis, c'est mieux

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

que ceci:

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

Le PEP-8 semble en réalité contradictoire ici. Bien que l'exemple sous "Longueur maximale de la ligne" illustre l'utilisation de parenthèses et d'un retrait standard de 4 caractères, la section "Indentation" indique que, en ce qui concerne les déclarations de fonction, "un retrait supplémentaire devrait être utilisé pour se distinguer clairement comme ligne suivante. ". Je ne vois pas pourquoi cela serait limité à "def" et non à "if".

3
mcote

Je le ferais de cette façon. Gardez-le en retrait loin de ne pas vous embrouiller.

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

Le conseil PEP-8 est ici.

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

Le code ci-dessous est conseillé

# 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)

Le code ci-dessous n'est pas conseillé

# 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

Dans un tel cas, je ferais simplement:

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

Pep-8 recommande la façon dont vous indentez votre exemple d'origine.

Maintenant, si vous êtes prêt à voler en face des guides de style si sacrés :-) vous pouvez déplacer l'opérateur à la ligne suivante:

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

Je ne suis pas vraiment fan de cela, je trouve en fait votre syntaxe originale assez facile à lire et je ne passerais pas beaucoup de temps à faire des singeries avec l'indentation ou les sauts de ligne.

0
stderr