问题
I have a very long query. I would like to split it in several lines in Python. A way to do it in JavaScript would be using several sentences and joining them with a +
operator (I know, maybe it\'s not the most efficient way to do it, but I\'m not really concerned about performance in this stage, just code readability). Example:
var long_string = \'some text not important. just garbage to\' +
\'illustrate my example\';
I tried doing something similar in Python, but it didn\'t work, so I used \\
to split the long string. However, I\'m not sure if this is the only/best/pythonicest way of doing it. It looks awkward.
Actual code:
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
回答1:
Are you talking about multi-line strings? Easy, use triple quotes to start and end them.
s = """ this is a very
long string if I had the
energy to type more and more ..."""
You can use single quotes too (3 of them of course at start and end) and treat the resulting string s
just like any other string.
NOTE: Just as with any string, anything between the starting and ending quotes becomes part of the string, so this example has a leading blank (as pointed out by @root45). This string will also contain both blanks and newlines.
I.e.,:
' this is a very\n long string if I had the\n energy to type more and more ...'
Finally, one can also construct long lines in Python like this:
s = ("this is a very"
"long string too"
"for sure ..."
)
which will not include any extra blanks or newlines (this is a deliberate example showing what the effect of skipping blanks will result in):
'this is a verylong string toofor sure ...'
No commas required, simply place the strings to be joined together into a pair of parenthesis and be sure to account for any needed blanks and newlines.
回答2:
If you don't want a multiline string but just have a long single line string, you can use parentheses, just make sure you don't include commas between the string segments, then it will be a 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)
In a SQL statement like what you're constructing, multiline strings would also be fine. But if the extra whitespace a multiline string would contain would be a problem, then this would be a good way to achieve what you want.
回答3:
Breaking lines by \
works for me. Here is an example:
longStr = "This is a very long string " \
"that I wrote to help somebody " \
"who had a question about " \
"writing long strings in Python"
回答4:
I found myself happy with this one:
string = """This is a
very long string,
containing commas,
that I split up
for readability""".replace('\n',' ')
回答5:
I find that when building long strings, you are usually doing something like building an SQL query, in which case this is best:
query = ' '.join(( # note double parens, join() takes an iterable
"SELECT foo",
"FROM bar",
"WHERE baz",
))
What Levon suggested is good, but might be vulnerable to mistakes:
query = (
"SELECT foo"
"FROM bar"
"WHERE baz"
)
query == "SELECT fooFROM barWHERE baz" # probably not what you want
回答6:
You can also concatenate variables in when using """ notation:
foo = '1234'
long_string = """fosdl a sdlfklaskdf as
as df ajsdfj asdfa sld
a sdf alsdfl alsdfl """ + foo + """ aks
asdkfkasdk fak"""
EDIT: Found a better way, with named params and .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)
回答7:
In Python >= 3.6 you can use Formatted string literals (f string)
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}'''
回答8:
This approach uses:
just one backslash to avoid an initial linefeed- almost no internal punctuation by using a triple quoted string
- strips away local indentation using the
textwrapinspect
module - uses python 3.6 formatted string interpolation ('f') for the
account_id
anddef_id
variables.
This way looks the most pythonic to me.
# 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}'''
)
Update: 1/29/2019 Incorporate @ShadowRanger's suggestion to use inspect.cleandoc
instead of textwrap.dedent
回答9:
For example:
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'
if the value of condition should be a string, you can do like this:
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'"
回答10:
I personally find the following to be the best (simple, safe and Pythonic) way to write raw SQL queries in Python, especially when using Python's sqlite3 module:
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
Pros
- Neat and simple code (Pythonic!)
- Safe from SQL injection
- Compatible with both Python 2 and Python 3 (it's Pythonic after all)
- No string concatenation required
- No need to ensure that the right-most character of each line is a space
Cons
- Since variables in the query are replaced by the
?
placeholder, it may become a little difficult to keep track of which?
is to be substituted by which Python variable when there are lots of them in the query.
回答11:
I find textwrap.dedent the best for long strings as described here:
def create_snippet():
code_snippet = textwrap.dedent("""\
int main(int argc, char* argv[]) {
return 0;
}
""")
do_something(code_snippet)
回答12:
Others have mentioned the parentheses method already, but I'd like to add that with parentheses, inline comments are allowed.
Comment on each fragment:
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.
)
Comment not allowed after continuation:
When using backslash line continuations (\
), comments are not allowed. You'll receive a SyntaxError: unexpected character after line continuation character
error.
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
Better comments for Regex strings:
Based on the example from 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)
回答13:
I usually use something like this:
text = '''
This string was typed to be a demo
on how could we write a multi-line
text in Python.
'''
If you want to remove annoying blank spaces in each line, you could do as follows:
text = '\n'.join(line.lstrip() for line in text.splitlines())
回答14:
Your actual code shouldn't work, you are missing whitespaces at the end of "lines" (eg: role.descr as roleFROM...
)
There is triplequotes for multiline string:
string = """line
line2
line3"""
It will contain the line breaks and extra spaces, but for SQL that's not a problem.
回答15:
You can also place the sql-statement in a seperate file action.sql
and load it in the py file with
with open('action.sql') as f:
query = f.read()
So the sql-statements will be separated from the python code. If there are parameters in the sql statement which needs to be filled from python, you can use string formating (like %s or {field})
回答16:
"À la" Scala way (but I think is the most pythonic way as OQ demands):
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(' | ',' ')
If you want final str without jump lines, just put \n
at the start of the first argument of the second replace:
.replace('\n | ',' ')`.
Note: the white line between "...templates." and "Also, ..." requires a whitespace after the |
.
回答17:
I use a recursive function to build complex SQL Queries. This technique can generally be used to build large strings while maintaining code readability.
# 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: Have a look at the awesome python-sqlparse library to pretty print SQL queries if needed. http://sqlparse.readthedocs.org/en/latest/api/#sqlparse.format
回答18:
Another option that I think is more readable when the code (e.g variable) is indented and the output string should be a one liner (no newlines):
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
回答19:
tl;dr: Use """\
and """
to wrap the string, as in
string = """\
This is a long string
spanning multiple lines.
"""
From the official python documentation:
String literals can span multiple lines. One way is using triple-quotes: """...""" or '''...'''. End of lines are automatically included in the string, but it’s possible to prevent this by adding a \ at the end of the line. The following example:
print("""\
Usage: thingy [OPTIONS]
-h Display this usage message
-H hostname Hostname to connect to
""")
produces the following output (note that the initial newline is not included):
Usage: thingy [OPTIONS]
-h Display this usage message
-H hostname Hostname to connect to
回答20:
I like this approach because it privileges reading. In cases where we have long strings there is no way! Depending on the level of indentation you are in and still limited to 80 characters per line... Well... No need to say anything else. In my view the python style guides are still very vague. I took the @Eero Aaltonen approach because it privileges reading and common sense. I understand that style guides should help us and not make our lives a mess. Thanks!
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
)
"""
回答21:
Hey try something like this hope it works, like in this format it will return you a continuous line like you have successfully enquired about this property`
"message": f'you have successfully inquired about '
f'{enquiring_property.title} Property owned by '
f'{enquiring_property.client}'
回答22:
From the official python documentation:
String literals can span multiple lines. One way is using triple-quotes: """...""" or '''...'''. End of lines are automatically included in the string, but it’s possible to prevent this by adding a \ at the end of the line. The following example:
print("""\
Usage: thingy [OPTIONS]
-h Display this usage message
-H hostname Hostname to connect to
""")
produces the following output (note that the initial newline is not included):
回答23:
Generally, I use list
and join
for multi-line comments/string.
lines = list()
lines.append('SELECT action.enter code here descr as "action", ')
lines.append('role.id as role_id,')
lines.append('role.descr as role')
lines.append('FROM ')
lines.append('public.role_action_def,')
lines.append('public.role,')
lines.append('public.record_def, ')
lines.append('public.action')
query = " ".join(lines)
you can use any string to join all this list element like '\n
'(newline) or ',
'(comma) or ''(space)
Cheers..!!
来源:https://stackoverflow.com/questions/10660435/pythonic-way-to-create-a-long-multi-line-string