Question Méthode Pythonic pour créer une longue chaîne multiligne


J'ai une très longue requête. Je voudrais le diviser en plusieurs lignes en Python. Une façon de le faire en JavaScript serait d'utiliser plusieurs phrases et de les rejoindre avec un + opérateur (je sais, ce n'est peut-être pas la façon la plus efficace de le faire, mais je ne suis pas vraiment préoccupé par les performances à ce stade, juste la lisibilité du code). Exemple:

var long_string = 'some text not important. just garbage to' +
                  'illustrate my example';

J'ai essayé de faire quelque chose de similaire en Python, mais ça n'a pas marché, alors j'ai utilisé \ diviser la longue chaîne. Cependant, je ne suis pas sûr que ce soit la seule façon / best / pythonicest de le faire. Ça a l'air bizarre. Code réel:

query = 'SELECT action.descr as "action", '\
    'role.id as role_id,'\
    'role.descr as role'\
    'FROM '\
    'public.role_action_def,'\
    'public.role,'\
    'public.record_def, '\
    'public.action'\
    'WHERE role.id = role_action_def.role_id AND'\
    'record_def.id = role_action_def.def_id AND'\
    'action.id = role_action_def.action_id AND'\
    'role_action_def.account_id = ' + account_id + ' AND'\
    'record_def.account_id=' + account_id + ' AND'\
    'def_id=' + def_id

778
2018-05-18 22:21


origine


Réponses:


Parlez-vous des chaînes multilignes? Facile, utilisez des guillemets pour les commencer et les terminer.

s = """ this is a very
        long string if I had the
        energy to type more and more ..."""

Vous pouvez aussi utiliser des guillemets simples (3 d'entre eux bien sûr au début et à la fin) et traiter la chaîne résultante s comme toute autre chaîne.

REMARQUE: Tout comme avec n'importe quelle chaîne, tout ce qui se trouve entre les guillemets de départ et de fin devient une partie de la chaîne, donc cet exemple a un blanc de début (comme indiqué par @ root45). Cette chaîne contiendra également des blancs et des retours à la ligne.

C'est à dire.,:

' this is a very\n        long string if I had the\n        energy to type more and more ...'

Enfin, on peut aussi construire de longues lignes en Python comme ceci:

 s = ("this is a very"
      "long string too"
      "for sure ..."
     )

Qui va ne pas inclure des blancs ou des retours à la ligne supplémentaires (il s'agit d'un exemple délibéré montrant l'effet de l'omission des blancs):

'this is a verylong string toofor sure ...'

Aucune virgule requise, placez simplement les chaînes à assembler entre deux parenthèses et assurez-vous de prendre en compte les blancs et les retours à la ligne nécessaires.


1335
2018-05-18 22:22



Si vous ne voulez pas de chaîne multiligne mais simplement une longue chaîne de caractères, vous pouvez utiliser des parenthèses, assurez-vous de ne pas inclure de virgules entre les segments de chaîne, alors ce sera un tuple.

query = ('SELECT   action.descr as "action", '
         'role.id as role_id,'
         'role.descr as role'
         ' FROM '
         'public.role_action_def,'
         'public.role,'
         'public.record_def, '
         'public.action'
         ' WHERE role.id = role_action_def.role_id AND'
         ' record_def.id = role_action_def.def_id AND'
         ' action.id = role_action_def.action_id AND'
         ' role_action_def.account_id = '+account_id+' AND'
         ' record_def.account_id='+account_id+' AND'
         ' def_id='+def_id)

Dans une instruction SQL comme ce que vous construisez, les chaînes multilignes seraient également bien. Mais si l'espace supplémentaire qu'une chaîne multiligne contient serait un problème, alors ce serait un bon moyen d'obtenir ce que vous voulez.


125
2018-05-18 22:26



Casser des lignes par \ travaille pour moi. Voici un exemple:

longStr = "This is a very long string " \
        "that I wrote to help somebody " \
        "who had a question about " \
        "writing long strings in Python"

100
2018-06-20 16:16



Je me suis trouvé heureux avec celui-ci:

string = """This is a
very long string,
containing commas,
that I split up
for readability""".replace('\n',' ')

34
2018-01-04 10:39



Je trouve que lorsque vous construisez des chaînes longues, vous faites généralement quelque chose comme construire une requête SQL, auquel cas c'est le mieux:

query = ' '.join((  # note double parens, join() takes an iterable
    "SELECT foo",
    "FROM bar",
    "WHERE baz",
))

Ce que Levon a suggéré est bon, mais pourrait être vulnérable aux erreurs:

query = (
    "SELECT foo"
    "FROM bar"
    "WHERE baz"
)

query == "SELECT fooFROM barWHERE baz"  # probably not what you want

27
2018-06-19 07:06



Vous pouvez également concaténer des variables lorsque vous utilisez la notation "" ":

foo = '1234'

long_string = """fosdl a sdlfklaskdf as
as df ajsdfj asdfa sld
a sdf alsdfl alsdfl """ +  foo + """ aks
asdkfkasdk fak"""

EDIT: trouvé un meilleur moyen, avec des paramètres nommés et .format ():

body = """
<html>
<head>
</head>
<body>
    <p>Lorem ipsum.</p>
    <dl>
        <dt>Asdf:</dt>     <dd><a href="{link}">{name}</a></dd>
    </dl>
    </body>
</html>
""".format(
    link='http://www.asdf.com',
    name='Asdf',
)

print(body)

20
2017-10-06 22:33



En Python> = 3.6, vous pouvez utiliser Littéraux de chaîne formatés (chaîne f)

query= f'''SELECT   action.descr as "action"
    role.id as role_id,
    role.descr as role
    FROM
    public.role_action_def,
    public.role,
    public.record_def,
    public.action
    WHERE role.id = role_action_def.role_id AND
    record_def.id = role_action_def.def_id AND
    action.id = role_action_def.action_id AND
    role_action_def.account_id = {account_id} AND
    record_def.account_id = {account_id} AND
    def_id = {def_id}'''

14
2018-04-25 18:47



Par exemple:

sql = ("select field1, field2, field3, field4 "
       "from table "
       "where condition1={} "
       "and condition2={}").format(1, 2)

Output: 'select field1, field2, field3, field4 from table 
         where condition1=1 and condition2=2'

si la valeur de condition doit être une chaîne, vous pouvez faire comme ceci:

sql = ("select field1, field2, field3, field4 "
       "from table "
       "where condition1='{0}' "
       "and condition2='{1}'").format('2016-10-12', '2017-10-12')

Output: "select field1, field2, field3, field4 from table where
         condition1='2016-10-12' and condition2='2017-10-12'"

8
2018-05-12 12:05



Personnellement, je trouve que ce qui suit est le meilleur moyen (simple, sûr et Python) d'écrire des requêtes SQL brutes en Python, en particulier lorsque vous utilisez Le module sqlite3 de Python:

query = '''
    SELECT
        action.descr as action,
        role.id as role_id,
        role.descr as role
    FROM
        public.role_action_def,
        public.role,
        public.record_def,
        public.action
    WHERE
        role.id = role_action_def.role_id
        AND record_def.id = role_action_def.def_id
        AND action.id = role_action_def.action_id
        AND role_action_def.account_id = ?
        AND record_def.account_id = ?
        AND def_id = ?
'''
vars = (account_id, account_id, def_id)   # a tuple of query variables
cursor.execute(query, vars)   # using Python's sqlite3 module

Avantages

  • Code soigné et simple (Pythonic!)
  • À l'abri de l'injection SQL
  • Compatible avec Python 2 et Python 3 (après tout, c'est Pythonic)
  • Aucune concaténation de chaîne requise
  • Pas besoin de s'assurer que le caractère le plus à droite de chaque ligne est un espace

Les inconvénients

  • Puisque les variables de la requête sont remplacées par ? placeholder, il peut devenir un peu difficile de garder une trace de ? est à remplacer par quelle variable Python quand il y en a beaucoup dans la requête.

5
2017-11-14 19:16



Votre code actuel ne devrait pas fonctionner, il vous manque des espaces à la fin des "lignes" (ex: role.descr as roleFROM...)

Il y a des triplequotes pour la chaîne multiligne:

string = """line
  line2
  line3"""

Il contiendra les sauts de ligne et les espaces supplémentaires, mais pour SQL ce n'est pas un problème.


3
2018-05-18 22:25



J'utilise habituellement quelque chose comme ceci:

text = '''
    This string was typed to be a demo
    on how could we write a multi-line
    text in Python.
'''

Si vous souhaitez supprimer des espaces vides gênants dans chaque ligne, vous pouvez procéder comme suit:

text = '\n'.join([line.lstrip() for line in text.split('\n')])

3
2018-06-21 17:36