web-dev-qa-db-fra.com

La méthode chaînée appelle le style d'indentation dans Python

En lisant PEP-8, je comprends que vous devez mettre la parenthèse fermante sur la même ligne que le dernier argument dans les appels de fonction:

ShortName.objects.distinct().filter(
    product__photo__stockitem__isnull=False)

Il est probablement préférable d'éviter les expressions longues. Mais si ce n'est pas souhaitable, comment feriez-vous pour les appels de méthode chaînés multiples? Le paren de fermeture doit-il être sur une nouvelle ligne?

ShortName.objects.distinct().filter(
    product__photo__stockitem__isnull=False
).values_list('value', flat=True)

Qu'en est-il des méthodes sans arguments? Comment les écrire sur plusieurs lignes sans référencer les valeurs de retour intermédiaires?

ShortName.objects.distinct(
    ).filter().values() # looks ugly

Mettre à jour: Il y a une question en double de Comment briser une ligne de méthodes chaînées en Python? . Le réponse acceptée suggère un familier du style jQuery de commencer chaque nouvelle ligne avec un point. L'auteur ne fournit aucune raison ou référence faisant autorité, je voudrais donc obtenir une confirmation sur un tel style ou une alternative.

90
katspaugh

Il s'agit d'un cas où un caractère de continuation de ligne est préférable aux parenthèses ouvertes.

ShortName.objects.distinct() \
         .filter().values()      # looks better

La nécessité de ce style devient plus évidente à mesure que les noms de méthode s'allongent et que les méthodes commencent à prendre des arguments:

return some_collection.get_objects(locator=l5) \
                      .get_distinct(case_insensitive=True) \
                      .filter(predicate=query(q5)) \
                      .values()

PEP 8 est destiné à être interprété avec une mesure de bon sens et un œil à la fois pratique et beau. Heureusement, violez toute directive PEP 8 qui entraîne un code laid ou difficile à lire.

Cela dit, si vous vous trouvez fréquemment en désaccord avec PEP 8, cela peut être un signe qu'il existe des problèmes de lisibilité qui transcendent votre choix d'espaces :-)

150
Raymond Hettinger

Je pense que le mieux est d'utiliser () pour forcer la jonction de ligne, et pour ce faire:

(ShortName.objects.distinct() # Look ma!
 .filter(product__photo__stickitem__isnull=False) # Comments are allowed
 .values_list('value', flat=True))

Ce n'est pas idéal, mais j'aime le fait qu'il se démarque visuellement et rend quelque peu évident la chaîne d'appels. Il autorise les commentaires de fin de ligne, qui \ la nouvelle ligne ne fonctionne pas.

53
user97370