Comment puis-je faire un saut de ligne (continuation de ligne) en Python?

1076

J'ai une longue ligne de code que je veux diviser en plusieurs lignes. Qu'est-ce que j'utilise et quelle est la syntaxe?

Par exemple, en ajoutant un tas de chaînes,

e = 'a' + 'b' + 'c' + 'd'

et l'avoir en deux lignes comme ceci:

e = 'a' + 'b' +
    'c' + 'd'
Rayon
la source

Réponses:

1212

Quelle est la ligne? Vous pouvez simplement avoir des arguments sur la ligne suivante sans aucun problème:

a = dostuff(blahblah1, blahblah2, blahblah3, blahblah4, blahblah5, 
            blahblah6, blahblah7)

Sinon, vous pouvez faire quelque chose comme ceci:

if a == True and \
   b == False

Consultez le guide de style pour plus d'informations.

De votre exemple de ligne:

a = '1' + '2' + '3' + \
    '4' + '5'

Ou:

a = ('1' + '2' + '3' +
    '4' + '5')

Notez que le guide de style indique que l'utilisation de la continuation implicite avec des parenthèses est préférable, mais dans ce cas particulier, l'ajout de parenthèses autour de votre expression n'est probablement pas la bonne solution.

Harley Holcombe
la source
35
En fait, vous avez la préférence du guide de style exactement à l'envers. La continuation implicite est préférable, la barre oblique inverse explicite ne doit être utilisée que si nécessaire.
Carl Meyer, le
35
Carl: Je ne suis pas d'accord, cela vient du guide: La façon préférée d'enrouler les longues lignes est d'utiliser la continuation de ligne implicite de Python entre parenthèses, crochets et accolades. Si nécessaire, vous pouvez ajouter une paire de parenthèses supplémentaires autour d'une expression, mais parfois l'utilisation d'une barre oblique inversée semble meilleure.
Jerub
15
L'élément clé de la citation du guide de style est «Si nécessaire, vous pouvez ajouter une paire de parenthèses supplémentaires autour d'une expression, mais parfois, utiliser une barre oblique inversée semble mieux. Le guide de style ne dit pas que vous devez ajouter des parenthèses, cela laisse le jugement de l'écrivain.
Tony Meyer
23
Vraisemblablement, PEP-8 a changé depuis l'ajout de ces commentaires, car il est assez clair maintenant que des parenthèses doivent être ajoutées pour encapsuler les longues lignes: "Les longues lignes peuvent être coupées sur plusieurs lignes en enveloppant les expressions entre parenthèses."
Daniel
46
PEP8 a en effet changé en 2010 - "parfois utiliser une barre oblique inversée semble mieux" a disparu.
e100
230

De PEP 8 - Guide de style pour le code Python :

Le moyen préféré pour encapsuler de longues lignes est d'utiliser la continuation de ligne implicite de Python entre parenthèses, crochets et accolades. Les longues lignes peuvent être coupées sur plusieurs lignes en enveloppant les expressions entre parenthèses. Ceux-ci doivent être utilisés de préférence à l'utilisation d'une barre oblique inverse pour la poursuite de la ligne.

Les contre-obliques peuvent parfois être appropriées. Par exemple, de longues instructions with multiples ne peuvent pas utiliser la continuation implicite, les contre-obliques sont donc acceptables:

with open('/path/to/some/file/you/want/to/read') as file_1, \
        open('/path/to/some/file/being/written', 'w') as file_2:
    file_2.write(file_1.read())

Un autre cas de ce type concerne les déclarations assert.

Assurez-vous de mettre en retrait la ligne continue de manière appropriée. L'endroit préféré pour contourner un opérateur binaire est après l'opérateur, pas avant lui. Quelques exemples:

class Rectangle(Blob):

    def __init__(self, width, height,
                 color='black', emphasis=None, highlight=0):
        if (width == 0 and height == 0 and
                color == 'red' and emphasis == 'strong' or
                highlight > 100):
            raise ValueError("sorry, you lose")
        if width == 0 and height == 0 and (color == 'red' or
                                           emphasis is None):
            raise ValueError("I don't think so -- values are %s, %s" %
                             (width, height))
        Blob.__init__(self, width, height,
                      color, emphasis, highlight)

PEP8 recommande désormais la convention inverse (pour la rupture lors d'opérations binaires) utilisée par les mathématiciens et leurs éditeurs pour améliorer la lisibilité.

Le style de rupture de Donald Knuth devant un opérateur binaire aligne les opérateurs verticalement, réduisant ainsi la charge de travail de l'œil lors de la détermination des éléments ajoutés et soustraits.

De PEP8: Une ligne doit-elle être interrompue avant ou après un opérateur binaire? :

Donald Knuth explique la règle traditionnelle dans sa série Ordinateurs et composition: "Bien que les formules d'un paragraphe se cassent toujours après les opérations et les relations binaires, les formules affichées se cassent toujours avant les opérations binaires" [3].

Suivre la tradition des mathématiques donne généralement un code plus lisible:

# Yes: easy to match operators with operands
income = (gross_wages
          + taxable_interest
          + (dividends - qualified_dividends)
          - ira_deduction
          - student_loan_interest)

Dans le code Python, il est permis de rompre avant ou après un opérateur binaire, tant que la convention est cohérente localement. Pour le nouveau code, le style de Knuth est suggéré.

[3]: Le TeXBook de Donald Knuth, pages 195 et 196

jfs
la source
3
NB: la recommandation a changé en 2010: "Les longues lignes peuvent être rompues ... en enveloppant les expressions entre parenthèses. Celles-ci devraient être utilisées de préférence à l'utilisation d'une barre oblique inverse ...", et toutes les barres obliques inverses ont été supprimées de l'exemple de code.
e100
1
@ e100: lisez le texte en gras ci-dessus: The preferred way .. is by using Python's implied line continuation inside parenthesesc'est la même chose que by wrapping expressions in parentheses. J'ai mis à jour l'exemple
jfs
10
Mais notez que «parfois, l'utilisation d'une barre oblique inversée semble meilleure» a également disparu.
e100
6
En 2015, le guide de style a été mis à jour pour préférer réellement la rupture avant les opérateurs binaires après les recherches de Donald Knuth en raison des améliorations perçues de la lisibilité.
J2C
70

Le danger d'utiliser une barre oblique inverse pour terminer une ligne est que si un espace est ajouté après la barre oblique inverse (ce qui, bien sûr, est très difficile à voir), la barre oblique inverse ne fait plus ce que vous pensiez.

Voir Idiomes et anti-idiomes Python (pour Python 2 ou Python 3 ) pour plus d'informations.

George V. Reilly
la source
8
C'est une des raisons pour lesquelles il est agréable de mieux voir les espaces de fuite; c'est à dire quelque chose comme set list listchars=trail:·dans vim. :)
Beau
25

Mettez un \à la fin de votre ligne ou mettez la déclaration entre parenthèses ( .. ). D' IBM :

b = ((i1 < 20) and
     (i2 < 30) and
     (i3 < 40))

ou

b = (i1 < 20) and \
    (i2 < 30) and \
    (i3 < 40)
SCdF
la source
24

Vous pouvez couper les lignes entre parenthèses et accolades. De plus, vous pouvez ajouter le caractère barre oblique inverse \à une ligne pour le rompre explicitement:

x = (tuples_first_value,
     second_value)
y = 1 + \
    2
Konrad Rudolph
la source
20

De la bouche du cheval: jonction de ligne explicite

Deux lignes physiques ou plus peuvent être jointes en lignes logiques à l'aide de caractères de barre oblique inverse ( \), comme suit: lorsqu'une ligne physique se termine par une barre oblique inverse qui ne fait pas partie d'un littéral de chaîne ou d'un commentaire, elle est jointe aux éléments suivants formant une seule ligne logique , en supprimant la barre oblique inverse et le caractère de fin de ligne suivant. Par exemple:

if 1900 < year < 2100 and 1 <= month <= 12 \
   and 1 <= day <= 31 and 0 <= hour < 24 \
   and 0 <= minute < 60 and 0 <= second < 60:   # Looks like a valid date
        return 1

Une ligne se terminant par une barre oblique inverse ne peut pas contenir de commentaire. Une barre oblique inverse ne continue pas un commentaire. Une barre oblique inversée ne continue pas un jeton, sauf pour les littéraux de chaîne (c'est-à-dire que les jetons autres que les littéraux de chaîne ne peuvent pas être divisés sur des lignes physiques à l'aide d'une barre oblique inverse). Une barre oblique inverse est illégale ailleurs sur une ligne en dehors d'un littéral de chaîne.

Jason Navarrete
la source
7
-1 car l'exemple est IMO unidiomatique. Les conditions composées peuvent avoir absolument des crochets englobants à la place, ce qui est plus pratique (pour l'édition ou le reconditionnement automatique) et idiomatique.
u0b34a0f6ae
4

Ce n'est peut-être pas la manière Pythonic, mais j'utilise généralement une liste avec la fonction join pour écrire une longue chaîne, comme les requêtes SQL:

query = " ".join([
    'SELECT * FROM "TableName"',
    'WHERE "SomeColumn1"=VALUE',
    'ORDER BY "SomeColumn2"',
    'LIMIT 5;'
])
Hardik Sondagar
la source
2

Extrait du Guide de l'auto-stoppeur de Python ( suite de la ligne ):

Lorsqu'une ligne de code logique dépasse la limite acceptée, vous devez la diviser en plusieurs lignes physiques. L'interpréteur Python joindra les lignes consécutives si le dernier caractère de la ligne est une barre oblique inverse. Cela est utile dans certains cas, mais devrait généralement être évité en raison de sa fragilité: un espace blanc ajouté à la fin de la ligne, après la barre oblique inverse, cassera le code et peut avoir des résultats inattendus.

Une meilleure solution consiste à utiliser des parenthèses autour de vos éléments. Laissé avec une parenthèse non fermée sur une fin de ligne, l'interpréteur Python rejoindra la ligne suivante jusqu'à ce que les parenthèses soient fermées. Le même comportement s'applique aux accolades bouclées et carrées.

Cependant , le plus souvent, devoir diviser une longue ligne logique est un signe que vous essayez de faire trop de choses en même temps, ce qui peut nuire à la lisibilité.

Cela dit, voici un exemple prenant en compte les importations multiples (lors du dépassement des limites de ligne, définies sur PEP-8 ), également appliqué aux chaînes en général:

from app import (
    app, abort, make_response, redirect, render_template, request, session
)
ivanleoncz
la source
1

Si vous voulez rompre votre ligne à cause d'une longue chaîne littérale, vous pouvez diviser cette chaîne en morceaux:

long_string = "a very long string"
print("a very long string")

sera remplacé par

long_string = (
  "a "
  "very "
  "long "
  "string"
)
print(
  "a "
  "very "
  "long "
  "string"
)

Sortie pour les deux instructions d'impression:

a very long string

Remarquez la parenthèse dans l'affectation.

Notez également que la rupture de chaînes littérales en morceaux permet d'utiliser le préfixe littéral uniquement sur des parties de la chaîne:

s = (
  "2+2="
  f"{2+2}"
)
jlaurens
la source
0

Utiliser l' opérateur de continuation de ligne c'est-à-dire "\"

Exemples:

# Ex.1

x = 1
s =  x + x**2/2 + x**3/3 \
       + x**4/4 + x**5/5 \
       + x**6/6 + x**7/7 \
       + x**8/8
print(s)
# 2.7178571428571425


----------


# Ex.2

text = ('Put several strings within parentheses ' \
        'to have them joined together.')
print(text)


----------


# Ex.3

x = 1
s =  x + x**2/2 \
       + x**3/3 \
       + x**4/4 \
       + x**6/6 \
       + x**8/8
print(s)
# 2.3749999999999996
seralouk
la source