web-dev-qa-db-fra.com

Comment écrire une très longue chaîne conforme à PEP8 et empêcher E501

Comme PEP8 suggère de rester en dessous de la règle des 80 colonnes pour votre programme python, comment puis-je m'y tenir avec de longues chaînes, c'est-à-dire.

s = "this is my really, really, really, really, really, really, really long string that I'd like to shorten."

Comment pourrais-je élargir ceci à la ligne suivante, c.-à-d.

s = "this is my really, really, really, really, really, really" + 
    "really long string that I'd like to shorten."
153
Federer

La concaténation implicite pourrait être la solution la plus propre:

s = "this is my really, really, really, really, really, really," \
    " really long string that I'd like to shorten."

Edit Après réflexion, je conviens que la suggestion de Todd d’utiliser des crochets plutôt que la poursuite de la ligne est préférable pour toutes les raisons qu’il donne. La seule hésitation que j'ai est qu'il est relativement facile de confondre les chaînes entre crochets et les n-uplets.

88
Michael Dunn

De plus, comme les constantes de chaîne voisines sont automatiquement concaténées, vous pouvez aussi le coder comme suit:

s = ("this is my really, really, really, really, really, really, "  
     "really long string that I'd like to shorten.")

Notez pas de signe plus, et j'ai ajouté la virgule supplémentaire et l'espace qui suit la mise en forme de votre exemple.

Personnellement, je n'aime pas les barres obliques inverses, et je me rappelle avoir lu quelque part que son utilisation est en réalité déconseillée au profit de cette forme plus explicite. Rappelez-vous "Explicit est meilleur qu'implicite."

Je considère que la barre oblique inverse est moins claire et moins utile car elle échappe au caractère de nouvelle ligne. Il n'est pas possible de mettre un commentaire de fin de ligne après s'il est nécessaire. Il est possible de faire cela avec des constantes de chaîne concaténées:

s = ("this is my really, really, really, really, really, really, " # comments ok
     "really long string that I'd like to shorten.")

J'ai utilisé une recherche Google de "longueur de ligne python" qui renvoie le lien PEP8 en tant que premier résultat, mais également des liens vers un autre bon message StackOverflow sur ce sujet: " Pourquoi Python PEP-8 devrait-il spécifier une longueur de ligne maximale de 79 caractères ? "

Une autre bonne phrase de recherche serait "continuation de la ligne python".

231
Todd

Vous avez perdu un espace et vous avez probablement besoin d'un caractère de continuation de ligne, c'est-à-dire. un \.

s = "this is my really, really, really, really, really, really" +  \
    " really long string that I'd like to shorten."

ou même:

s = "this is my really, really, really, really, really, really"  \
    " really long string that I'd like to shorten."

Parens fonctionnerait également au lieu de continuer la ligne, mais vous risqueriez de penser que vous aviez l’intention d’avoir un Tuple et que vous veniez d’oublier une virgule. Prenons par exemple:

s = ("this is my really, really, really, really, really, really"
    " really long string that I'd like to shorten.")

contre:

s = ("this is my really, really, really, really, really, really",
    " really long string that I'd like to shorten.")

Avec le typage dynamique de Python, le code peut être exécuté dans les deux sens, mais produire des résultats incorrects avec celui que vous ne vouliez pas.

13
retracile

Je pense que le mot le plus important dans votre question était "suggère". 

Les normes de codage sont des choses amusantes. Lorsqu’ils ont été écrits, les instructions fournies ont souvent une très bonne base (par exemple, la plupart des terminaux ne pouvant pas afficher plus de 80 caractères sur une ligne), mais ils deviennent avec le temps obsolètes sur le plan fonctionnel, mais toujours strictement appliqués. Je suppose que ce que vous devez faire ici est de peser le mérite relatif de "casser" cette suggestion particulière contre la lisibilité et la maintenabilité principale de votre code.

Désolé, cela ne répond pas directement à votre question.

12
ZombieSheep

Barre oblique inverse:

s = "this is my really, really, really, really, really, really" +  \
    "really long string that I'd like to shorten."

ou envelopper dans parens:

s = ("this is my really, really, really, really, really, really" + 
    "really long string that I'd like to shorten.")
4
recursive

Avec un \, vous pouvez développer des instructions sur plusieurs lignes:

s = "this is my really, really, really, really, really, really" + \
"really long string that I'd like to shorten."

devrait marcher.

1
Ikke

J'ai tendance à utiliser quelques méthodes non mentionnées ici pour spécifier des chaînes de grande taille, mais celles-ci sont destinées à des scénarios très spécifiques. YMMV ...

  • Blobs de texte sur plusieurs lignes, souvent avec des jetons formatés (pas tout à fait ce que vous demandiez, mais toujours utile):

    error_message = '''
    I generally like to see how my helpful, sometimes multi-line error
    messages will look against the left border.
    '''.strip()
    
  • Développez la variable pièce par pièce selon la méthode d'interpolation de chaîne que vous préférez:

    var = 'This is the start of a very,'
    var = f'{var} very long string which could'
    var = f'{var} contain a ridiculous number'
    var = f'{var} of words.'
    
  • Lisez-le dans un fichier. PEP-8 ne limite pas la longueur des chaînes d'un fichier; juste les lignes de votre code. :)

  • Utilisez brute-force ou votre éditeur pour scinder la chaîne en lignes managaebles à l'aide des nouvelles lignes, puis supprimez toutes les lignes. (Similaire à la première technique que j'ai énumérée):

    foo = '''
    agreatbigstringthatyoudonotwanttohaveanyne
    wlinesinbutforsomereasonyouneedtospecifyit
    verbatimintheactualcodejustlikethis
    '''.replace('\n', '')
    
0
Larold

Options disponibles:

  • barre oblique inverse: "foo" \ "bar"
  • signe plus suivi de barre oblique inverse: "foo" + \ "bar"
  • parenthèses:
    • ("foo" "bar")
    • parenthèses avec signe plus: ("foo" + "bar")
    • PEP8, E502: la barre oblique inverse est redondante entre crochets

Éviter

Évitez les crochets avec une virgule: ("foo", "bar") qui définit un tuple.


>>> s = "a" \
... "b"
>>> s
'ab'
>>> type(s)
<class 'str'>
>>> s = "a" + \
... "b"
>>> s
'ab'
>>> type(s)
<class 'str'>
>>> s = ("a"
... "b")
>>> type(s)
<class 'str'>
>>> print(s)
ab
>>> s = ("a",
... "b")
>>> type(s)
<class 'Tuple'>
>>> s = ("a" + 
... "b")
>>> type(s)
<class 'str'>
>>> print(s)
ab
>>> 
0
marcanuy

J'ai utilisé textwrap.dedent par le passé. C'est un peu lourd, donc je préfère les continuations de lignes maintenant, mais si vous voulez vraiment le retrait de bloc, je pense que c'est génial. 

Exemple de code (où l’ajustage consiste à supprimer le premier '\ n' avec une tranche):

import textwrap as tw
x = """
       This is a yet another test.
       This is only a test"""
print(tw.dedent(x[1:]))

Explication: 

D'après ce que je peux dire, dedent calcule l'indentation en fonction de l'espace blanc dans la première ligne de texte avant une nouvelle ligne. J'ai donc ajouté une nouvelle ligne pour faciliter l'alignement du code. Pour éviter la nouvelle ligne, vous devez ajouter à la première ligne de texte un espace supplémentaire afin que les lignes suivantes voient leur retrait réduit à votre guise. Si vous voulez le modifier, vous pouvez facilement le réimplémenter en utilisant le module re.

Cette méthode a des limites en ce que le chemin des très longues lignes est toujours plus long que ce que vous voulez, auquel cas d'autres méthodes qui concaténent des chaînes sont plus appropriées.

0
MrMas

Ce sont toutes d'excellentes réponses, mais je ne pouvais pas trouver de plug-in d'éditeur qui m'aiderait à éditer des chaînes "implicitement concaténées". J'ai donc écrit un package pour me faciliter la tâche.

Sur pip (installer des paragraphes) si celui qui se promène dans ce vieux fil aimerait le vérifier. Formate les chaînes multi-lignes comme le fait le HTML (compresse les espaces, deux nouvelles lignes pour un nouveau paragraphe, ne vous inquiétez pas des espaces entre les lignes).

from paragraphs import par

class SuddenDeathError(Exception):
    def __init__(self, cause: str) -> None:
        self.cause = cause

    def __str__(self):
par(
    f"""
    Y - e - e - e - es, Lord love you! Why should she die of
    influenza? She come through diphtheria right enough the year
    before. I saw her with my own eyes. Fairly blue with it, she was.They
    all thought she was dead; but my father he kept ladling gin down
    her throat til she came to so sudden that she bit the bowl off the
    spoon. 

    What call would a woman with that strength in her have to die of
    influenze? What become of her new straw hat that should have
    come to me? Somebody pinched it; and what I say is, them as pinched
    it done her in."""
)

devient ...

Y - e - e - e - es, Lord love you! Why should she die of influenza? She come through...

What call would a woman with that strength in her have to die of influenza?  What...

Tout s'aligne facilement avec (Vim) 'gq'

0
Shay