J'ai une très longue requête. Je voudrais le scinder en plusieurs lignes en Python. Une façon de le faire en JavaScript consisterait à utiliser plusieurs phrases et à les joindre à un opérateur +
(je sais, ce n'est peut-être pas le moyen le plus efficace de le faire, mais je ne m'inquiète pas vraiment des 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 cela n'a pas fonctionné. J'ai donc utilisé \
pour scinder la longue chaîne. Cependant, je ne suis pas sûr que ce soit le seul/meilleur/meilleur moyen de le faire. Cela semble bizarre. Code actuel:
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
Parlez-vous des chaînes multi-lignes? Facile, utilisez des guillemets triples 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 également utiliser des guillemets simples (3 bien sûr au début et à la fin) et traiter la chaîne résultante s
comme toute autre chaîne.
NOTE: Comme avec n'importe quelle chaîne, tout ce qui se situe entre les guillemets de début et de fin devient une partie de la chaîne. Cet exemple comporte donc un blanc (comme indiqué par @ root45). Cette chaîne contiendra également des blancs et des nouvelles lignes.
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 dans Python comme ceci:
s = ("this is a very"
"long string too"
"for sure ..."
)
qui not inclura tous les espaces ou les nouvelles lignes (il s’agit d’un exemple délibéré montrant l’effet de la suppression des espaces):
'this is a verylong string toofor sure ...'
Aucune virgule requise, il suffit de placer les chaînes à assembler dans une paire de parenthèses et d’être sûr de prendre en compte les espaces et les nouvelles lignes nécessaires.
Si vous ne voulez pas de chaîne multiligne mais que vous avez une longue chaîne simple, vous pouvez utiliser des parenthèses, assurez-vous simplement de ne pas inclure de virgule entre les segments de chaîne, ce sera alors 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 telle que celle que vous construisez, des chaînes multilignes conviendraient également. Mais si les espaces supplémentaires qu'une chaîne multiligne contiendrait poseraient un problème, ce serait un bon moyen de réaliser ce que vous voulez.
Couper les lignes de \
fonctionne 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"
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',' ')
Je trouve que lorsque vous construisez de longues chaînes, vous faites habituellement quelque chose comme une requête SQL, auquel cas il vaut 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
Vous pouvez également concaténer des variables en utilisant la notation "" ":
foo = '1234'
long_string = """fosdl a sdlfklaskdf as
as df ajsdfj asdfa sld
a sdf alsdfl alsdfl """ + foo + """ aks
asdkfkasdk fak"""
EDIT: Trouver un meilleur moyen, avec nommés params 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)
Dans 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}'''
Cette approche utilise:
inspect
account_id
et def_id
.Cette façon me semble la plus pythonique.
# import textwrap # See update to answer below
import inspect
# query = textwrap.dedent(f'''\
query = inspect.cleandoc(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}'''
)
Mise à jour: 29/01/2019 Incorporer la suggestion de @ ShadowRanger d'utiliser inspect.cleandoc
au lieu de textwrap.dedent
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'"
Personnellement, je trouve que le texte suivant est le meilleur moyen (simple, sûr et Pythonic) d’écrire des requêtes SQL brutes en Python, en particulier lors de l’utilisation de 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
?
, il peut devenir un peu difficile de garder trace de ce que ?
doit être remplacé par quelle variable Python quand il y a beaucoup d'entre eux dans la requête.Je trouve textwrap.dedent
le meilleur pour les longues chaînes comme décrit ici :
_def create_snippet():
code_snippet = textwrap.dedent("""\
int main(int argc, char* argv[]) {
return 0;
}
""")
do_something(code_snippet)
_
D'autres ont déjà mentionné la méthode des parenthèses, mais j'aimerais ajouter qu'avec les parenthèses, les commentaires en ligne sont autorisés.
nursery_rhyme = (
'Mary had a little lamb,' # Comments are great!
'its fleece was white as snow.'
'And everywhere that Mary went,'
'her sheep would surely go.' # What a pesky sheep.
)
Lors de l'utilisation de continuations de lignes obliques inverses (\
), les commentaires ne sont pas autorisés. Vous recevrez une erreur SyntaxError: unexpected character after line continuation character
.
nursery_rhyme = 'Mary had a little lamb,' \ # These comments
'its fleece was white as snow.' \ # are invalid!
'And everywhere that Mary went,' \
'her sheep would surely go.'
# => SyntaxError: unexpected character after line continuation character
Basé sur l'exemple de https://docs.python.org/3/library/re.html#re.VERBOSE ,
a = re.compile(
r'\d+' # the integral part
r'\.' # the decimal point
r'\d*' # some fractional digits
)
# Using VERBOSE flag, IDE usually can't syntax highight the string comment.
a = re.compile(r"""\d + # the integral part
\. # the decimal point
\d * # some fractional digits""", re.X)
J'utilise habituellement quelque chose comme ça:
text = '''
This string was typed to be a demo
on how could we write a multi-line
text in Python.
'''
Si vous souhaitez supprimer les espaces vides ennuyeux de chaque ligne, procédez comme suit:
text = '\n'.join(line.lstrip() for line in text.splitlines())
Votre code actuel ne devrait pas fonctionner, il manque des espaces à la fin des "lignes" (par exemple: role.descr as roleFROM...
)
Il y a des triples cotes pour les chaînes multilignes:
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.
Vous pouvez également placer l'instruction sql dans un fichier séparé action.sql
et la charger dans le fichier py avec
with open('action.sql') as f:
query = f.read()
Ainsi, les instructions sql seront séparées du code python. S'il existe des paramètres dans l'instruction SQL qui doivent être remplis à partir de python, vous pouvez utiliser le formatage de chaîne (comme% s ou {champ}).
"À la" Scala moyen (mais je pense que c'est le moyen le plus pythonique comme l'exige l'OQ):
description = """
| The intention of this module is to provide a method to
| pass meta information in markdown_ header files for
| using it in jinja_ templates.
|
| Also, to provide a method to use markdown files as jinja
| templates. Maybe you prefer to see the code than
| to install it.""".replace('\n | \n','\n').replace(' | ',' ')
Si vous voulez une chaîne finale sans lignes de saut, il suffit de mettre \n
au début du premier argument du deuxième remplacement:
.replace('\n | ',' ')`.
Remarque: la ligne blanche entre "... modèles". et "En outre, ..." nécessite un espace après le |
.
J'utilise une fonction récursive pour construire des requêtes SQL complexes. Cette technique peut généralement être utilisée pour construire de grandes chaînes tout en maintenant la lisibilité du code.
# Utility function to recursively resolve SQL statements.
# CAUTION: Use this function carefully, Pass correct SQL parameters {},
# TODO: This should never happen but check for infinite loops
def resolveSQL(sql_seed, sqlparams):
sql = sql_seed % (sqlparams)
if sql == sql_seed:
return ' '.join([x.strip() for x in sql.split()])
else:
return resolveSQL(sql, sqlparams)
P.S: Jetez un coup d’œil à l’impressionnante bibliothèque python-sqlparse pour imprimer de jolies requêtes SQL si nécessaire. http://sqlparse.readthedocs.org/fr/latest/api/#sqlparse.format
Une autre option qui, à mon avis, est plus lisible lorsque le code (par exemple, une variable) est en retrait et que la chaîne de sortie doit être une ligne (sans nouvelle ligne):
def some_method():
long_string = """
a presumptuous long string
which looks a bit nicer
in a text editor when
written over multiple lines
""".strip('\n').replace('\n', ' ')
return long_string
tl; dr: Utilisez """\
et """
pour envelopper la chaîne , comme dans
string = """\
This is a long string
spanning multiple lines.
"""
À partir de la documentation officielle python :
Les littéraux de chaîne peuvent s'étendre sur plusieurs lignes. L'une des méthodes consiste à utiliser des guillemets triples: "" "..." "" ou "" ... ". Les fins de lignes sont automatiquement incluses dans la chaîne, mais il est possible d’éviter cela en ajoutant un\à la fin de la ligne. L'exemple suivant:
print("""\
Usage: thingy [OPTIONS]
-h Display this usage message
-H hostname Hostname to connect to
""")
produit le résultat suivant (notez que la nouvelle ligne initiale n'est pas incluse):
Usage: thingy [OPTIONS]
-h Display this usage message
-H hostname Hostname to connect to
À partir de la documentation officielle python :
Les littéraux de chaîne peuvent s'étendre sur plusieurs lignes. L'une des méthodes consiste à utiliser des guillemets triples: "" "..." "" ou "" ... ". Les fins de lignes sont automatiquement incluses dans la chaîne, mais il est possible d’éviter cela en ajoutant un\à la fin de la ligne. L'exemple suivant:
print("""\
Usage: thingy [OPTIONS]
-h Display this usage message
-H hostname Hostname to connect to
""")
produit le résultat suivant (notez que la nouvelle ligne initiale n'est pas incluse):
Hey, essayez quelque chose comme ça, espérons que cela fonctionne, comme dans ce format, il vous retournera une ligne continue comme si vous aviez demandé avec succès à propos de cette propriété "
"message": f'you have successfully inquired about '
f'{enquiring_property.title} Property owned by '
f'{enquiring_property.client}'
J'aime cette approche parce qu'elle privilégie la lecture. Dans les cas où nous avons de longues chaînes, il n'y a aucun moyen! En fonction du niveau d'indentation dans lequel vous vous trouvez et toujours limité à 80 caractères par ligne ... Bon ... Pas besoin de dire autre chose. À mon avis, les guides de style python sont encore très vagues. J'ai choisi l'approche @Eero Aaltonen car elle privilégie la lecture et le bon sens. Je comprends que les guides de style devraient nous aider et non pas gâcher nos vies. Merci!
class ClassName():
def method_name():
if condition_0:
if condition_1:
if condition_2:
some_variable_0 =\
"""
some_js_func_call(
undefined,
{
'some_attr_0': 'value_0',
'some_attr_1': 'value_1',
'some_attr_2': '""" + some_variable_1 + """'
},
undefined,
undefined,
true
)
"""