Parfois, je casse de longues conditions if
sur plusieurs lignes. La façon la plus évidente de le faire est:
if (cond1 == 'val1' and cond2 == 'val2' and
cond3 == 'val3' and cond4 == 'val4'):
do_something
N'est pas très très attrayant visuellement, car l'action se confond avec les conditions. Cependant, c'est la manière naturelle d'utiliser l'indentation Python correcte de 4 espaces.
Pour le moment j'utilise:
if ( cond1 == 'val1' and cond2 == 'val2' and
cond3 == 'val3' and cond4 == 'val4'):
do_something
Mais ce n'est pas très joli. :-)
Pouvez-vous recommander une autre façon?
python
coding-style
if-statement
Eli Bendersky
la source
la source
pep8
critères du package. Lepep8
du paquet de # 126 question est de fixer le paquet à suivre strictement les spécifications de pep8. La discussion sur le problème comprend quelques suggestions de style également vues ici.Réponses:
Vous n'avez pas besoin d'utiliser 4 espaces sur votre deuxième ligne conditionnelle. Peut-être utiliser:
N'oubliez pas non plus que l'espace est plus flexible que vous ne le pensez:
Les deux sont assez laids cependant.
Peut-être perdre les crochets (le Guide de style décourage cela cependant)?
Cela vous donne au moins une certaine différenciation.
Ou même:
Je pense que je préfère:
Voici le Style Guide , qui (depuis 2010) recommande d'utiliser des crochets.
la source
and
etif
aussi.J'ai eu recours à ce qui suit dans le cas dégénéré où il s'agit simplement de ET ou de OU.
Il rase quelques caractères et montre clairement qu'il n'y a aucune subtilité à la condition.
la source
if destroy_world and DestroyTheWorld() == world_is_destroyed: ...
. Génial, maintenant vous venez de détruire le monde par accident. COMMENT PEUX-TU?Quelqu'un doit défendre l' utilisation des espaces verticaux ici! :)
Cela rend chaque condition clairement visible. Il permet également une expression plus nette des conditions plus complexes:
Oui, nous échangeons un peu d'immobilier vertical pour plus de clarté. Ça vaut le coup IMO.
la source
and
aussi bien queor
) est après l'opérateur, pas avant lui.PEP8
mais il est plus difficile de déterminer l'opération logique avec laquelle vous enchaînez. Je voudrais échouer si cela venait à mon bureau via la révision du code.Je préfère ce style quand j'ai une condition if terriblement grande:
la source
and
etor
au début de la ligne viole le PEP 0008 , qui stipule que "l'endroit préféré pour contourner un opérateur binaire est après l'opérateur, pas avant lui". . J'aime avoir le crochet de fermeture et les deux points sur leur propre ligne pour séparer la condition if du corps, (et il est parfaitement possible de le faire tout en gardant vos opérateurs booléens à la fin de la ligne pour la conformité PEP-0008).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.
(le style de Knuth est de commencer la ligne avec l'opérateur).Voici mon point de vue très personnel: les conditions longues sont (à mon avis) une odeur de code qui suggère une refactorisation en une fonction / méthode à retour booléen. Par exemple:
Maintenant, si je trouvais un moyen de rendre les conditions multilignes plus belles, je me contenterais probablement de les avoir et de sauter le refactoring.
En revanche, les faire perturber mon sens esthétique incite à la refactorisation.
Ma conclusion, par conséquent, est que les conditions de plusieurs lignes doivent sembler moches et c'est une incitation à les éviter.
la source
Cela ne s'améliore pas tellement mais ...
la source
Je suggère de déplacer le
and
mot - clé vers la deuxième ligne et de mettre en retrait toutes les lignes contenant des conditions avec deux espaces au lieu de quatre:C'est exactement ainsi que je résous ce problème dans mon code. Le fait d'avoir un mot-clé comme premier mot de la ligne rend la condition beaucoup plus lisible et la réduction du nombre d'espaces distingue encore la condition de l'action.
la source
Il semble intéressant de citer PEP 0008 (le guide de style officiel de Python), car il commente ce problème de manière modeste:
Notez le "non limité à" dans la citation ci-dessus; outre les approches suggérées dans le guide de style, certaines de celles suggérées dans d'autres réponses à cette question sont également acceptables.
la source
Voici ce que je fais, rappelez-vous que "tous" et "tous" accepte un itérable, donc je mets simplement une condition longue dans une liste et laisse "tous" faire le travail.
la source
Je suis surpris de ne pas voir ma solution préférée,
Étant donné qu'il
and
s'agit d'un mot clé, il est mis en surbrillance par mon éditeur et semble suffisamment différent du do_something en dessous.la source
Pour ajouter à ce que @krawyoti a dit ... Les longues conditions sentent parce qu'elles sont difficiles à lire et difficiles à comprendre. L'utilisation d'une fonction ou d'une variable rend le code plus clair. En Python, je préfère utiliser l'espace vertical, entourer les parenthèses et placer les opérateurs logiques au début de chaque ligne afin que les expressions ne ressemblent pas à "flottantes".
Si les conditions doivent être évaluées plusieurs fois, comme dans une
while
boucle, il est préférable d'utiliser une fonction locale.la source
Personnellement, j'aime ajouter du sens aux longues instructions if. Je devrais rechercher dans le code pour trouver un exemple approprié, mais voici le premier exemple qui me vient à l'esprit: disons que je rencontre une logique excentrique où je veux afficher une certaine page en fonction de nombreuses variables.
Anglais: "Si l'utilisateur connecté n'est PAS un enseignant administrateur, mais est juste un enseignant régulier, et n'est pas un élève lui-même ..."
Bien sûr, cela peut sembler correct, mais lire ces déclarations if représente beaucoup de travail. Que diriez-vous d'attribuer la logique à une étiquette qui a du sens. Le "label" est en fait le nom de la variable:
Cela peut sembler idiot, mais vous pouvez avoir une autre condition dans laquelle vous souhaitez afficher UNIQUEMENT un autre élément si, et seulement si, vous affichez le panneau de l'enseignant OU si l'utilisateur a accès à cet autre panneau spécifique par défaut:
Essayez d'écrire la condition ci-dessus sans utiliser de variables pour stocker et étiqueter votre logique, et non seulement vous vous retrouvez avec une déclaration logique très compliquée et difficile à lire, mais vous venez également de vous répéter. Bien qu'il existe des exceptions raisonnables, n'oubliez pas: ne vous répétez pas (SEC).
la source
"all" et "any" sont agréables pour les nombreuses conditions du même type de cas. MAIS ils évaluent toujours toutes les conditions. Comme le montre cet exemple:
la source
all()
là, à moins que vous ne les enveloppiez chacune dans un lambda et que vous n'utilisiez votref()
astuce, elles vont toutes être évaluées. En d'autres termes, Aaron: Je pense qu'Anders essayait de parler des conditions en général, en utilisant des callables comme exemple spécifique; mais votre réplique ne s'applique qu'aux fonctions.(J'ai légèrement modifié les identifiants car les noms à largeur fixe ne sont pas représentatifs du vrai code - du moins pas du vrai code que je rencontre - et démentiront la lisibilité d'un exemple.)
Cela fonctionne bien pour "et" et "ou" (il est important qu'ils soient premiers sur la deuxième ligne), mais beaucoup moins pour les autres conditions longues. Heureusement, les premiers semblent être le cas le plus courant tandis que les seconds sont souvent facilement réécrits avec une variable temporaire. (Ce n'est généralement pas difficile, mais il peut être difficile ou beaucoup moins évident / lisible de conserver le court-circuitage de "et" / "ou" lors de la réécriture.)
Depuis que j'ai trouvé cette question dans votre article de blog sur C ++ , je vais inclure que mon style C ++ est identique:
la source
Clair et simple, passe également les contrôles pep8:
Ces derniers temps, j'ai préféré les fonctions
all
etany
, car je mélange rarement les comparaisons And et Or, cela fonctionne bien et présente l'avantage supplémentaire de ne pas arriver tôt avec la compréhension des générateurs:N'oubliez pas de passer en un seul itérable! Passer des N-arguments n'est pas correct.
Remarque:
any
c'est comme beaucoup deor
comparaisons,all
c'est comme beaucoup deand
comparaisons.Cela se combine bien avec les compréhensions de générateur, par exemple:
En savoir plus sur: la compréhension du générateur
la source
Et si nous insérons seulement une ligne vierge supplémentaire entre la condition et le corps et faisons le reste de manière canonique?
ps J'utilise toujours des tabulations, pas des espaces; Je ne peux pas affiner ...
la source
and
etor
doivent commencer sur la ligne suivanteCe que je fais habituellement, c'est:
de cette façon l'accolade de fermeture et le côlon marquent visuellement la fin de notre condition.
la source
and
ouor
.Tous les répondants qui fournissent également des conditions multiples pour l'instruction if sont tout aussi laids que le problème présenté. Vous ne résolvez pas ce problème en faisant la même chose ..
Même la réponse PEP 0008 est répugnante.
Voici une approche beaucoup plus lisible
Vous voulez que je mange mes mots? Convainquez-moi que vous avez besoin de multi-conditions et je vais littéralement l'imprimer et le manger pour votre amusement.
la source
Je pense que la solution de @ zkanda serait bonne avec une petite touche. Si vous aviez vos conditions et valeurs dans leurs propres listes respectives, vous pourriez utiliser une compréhension de liste pour faire la comparaison, ce qui rendrait les choses un peu plus générales pour ajouter des paires condition / valeur.
Si je voulais coder en dur une déclaration comme celle-ci, je l'écrirais comme ceci pour la lisibilité:
Et juste pour lancer une autre solution avec un
iand
opérateur :la source
all(map(eq, have, expected))
. (avecfrom operator import eq
)Juste quelques autres idées aléatoires par souci d'exhaustivité. S'ils fonctionnent pour vous, utilisez-les. Sinon, vous feriez probablement mieux d'essayer autre chose.
Vous pouvez également le faire avec un dictionnaire:
Cette option est plus compliquée, mais vous pouvez également la trouver utile:
Ne sais pas si cela fonctionne pour vous, mais c'est une autre option à considérer. Voici une autre façon:
Je n'ai pas testé les deux derniers, mais les concepts devraient être suffisants pour vous permettre de continuer si c'est ce que vous voulez.
(Et pour mémoire, s'il ne s'agit que d'une seule fois, vous feriez probablement mieux d'utiliser la méthode que vous avez présentée au début. Si vous faites la comparaison à de nombreux endroits, ces méthodes peuvent améliorer suffisamment la lisibilité pour rendre vous ne vous sentez pas si mal du fait qu'ils sont un peu hacky.)
la source
J'ai eu du mal à trouver un moyen décent de le faire aussi, alors j'ai juste eu une idée (pas une balle d'argent, car c'est principalement une question de goût).
Je trouve quelques mérites dans cette solution par rapport aux autres que j'ai vus, à savoir, vous obtenez exactement 4 espaces supplémentaires d'indentation (bool), permettant à toutes les conditions de s'aligner verticalement, et le corps de l'instruction if peut être indenté dans d'une manière claire (ish). Cela conserve également les avantages de l'évaluation en court-circuit des opérateurs booléens, mais ajoute bien sûr la surcharge d'un appel de fonction qui ne fait essentiellement rien. Vous pourriez argumenter (valablement) que n'importe quelle fonction renvoyant son argument pourrait être utilisée ici au lieu de bool, mais comme je l'ai dit, c'est juste une idée et c'est finalement une question de goût.
Assez drôle, alors que j'écrivais ceci et pensais au «problème», j'ai eu une autre idée, qui supprime les frais généraux d'un appel de fonction. Pourquoi ne pas indiquer que nous allons entrer dans une condition complexe en utilisant des paires de parenthèses supplémentaires? Disons, 2 de plus, pour donner un joli retrait de 2 espaces des sous-conditions par rapport au corps de l'instruction if. Exemple:
J'aime un peu ça parce que quand vous le regardez, une cloche sonne immédiatement dans votre tête en disant "hé, il se passe quelque chose de complexe ici!" . Oui, je sais que les parenthèses n'aident pas à la lisibilité, mais ces conditions devraient apparaître assez rarement, et quand elles apparaîtront, vous devrez quand même vous arrêter et les lire attentivement (car elles sont complexes ).
Quoi qu'il en soit, juste deux autres propositions que je n'ai pas vues ici. J'espère que cela aide quelqu'un :)
la source
Vous pouvez le diviser en deux lignes
Ou même ajouter une condition à la fois. De cette façon, au moins, il sépare l'encombrement du
if
.la source
Je sais que ce fil est ancien, mais j'ai du code Python 2.7 et PyCharm (4.5) se plaint toujours de ce cas:
Même avec l'avertissement PEP8 "ligne visuellement indentée avec le même retrait que la ligne logique suivante", le code réel est complètement OK? Ce n'est pas "trop indenté?"
... il y a des moments où je souhaite que Python ait mordu la balle et soit parti avec des accolades frisées. Je me demande combien de bugs ont été introduits accidentellement au fil des ans en raison d'une indentation accidentelle ...
la source
Mettez vos conditions dans une liste, puis faites un smth. comme:
la source
Je trouve que lorsque j'ai de longues conditions, j'ai souvent un corps de code court. Dans ce cas, je viens de double indentation du corps, ainsi:
la source
ou si c'est plus clair:
Il n'y a aucune raison que le retrait soit un multiple de 4 dans ce cas, par exemple, voir "Aligné avec le délimiteur d'ouverture":
http://google-styleguide.googlecode.com/svn/trunk/pyguide.html?showone=Indentation#Indentation
la source
Voici une autre approche:
Cela permet également d'ajouter facilement une autre condition sans modifier l'instruction if en ajoutant simplement une autre condition à la liste:
la source
J'utilise habituellement:
la source
si notre condition if & an else doit exécuter plusieurs instructions à l'intérieur, nous pouvons écrire comme ci-dessous. Chaque fois que nous avons sinon un exemple avec une déclaration à l'intérieur.
Merci ça marche pour moi.
la source
Pardonnez ma noblesse, mais il se trouve que je ne connais pas aussi bien #Python que n'importe lequel d'entre vous ici, mais il se trouve que j'ai trouvé quelque chose de similaire lors de l'écriture de mes propres objets dans une modélisation BIM 3D, donc j'adapterai mon algorithme à celui du python.
Le problème que je trouve ici, est double face:
Faites pour contourner tous ces problèmes, votre script doit aller comme ça
Avantages de cette méthode:
Le script est lisible.
Le script peut être facilement maintenu.
J'espère que cela vous aidera tous
la source