Pythonic way to create a long multi-line string
我有一个很长的问题。我想用Python把它分成几行。在JavaScript中实现这一点的一种方法是使用几个句子并将它们与
1 2 | var long_string = 'some text not important. just garbage to' + 'illustrate my example'; |
我尝试在Python中做类似的事情,但是没有成功,所以我使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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 2 3 | s =""" this is a very long string if I had the energy to type more and more ...""" |
您也可以使用单引号(当然在开始和结束时可以使用其中的3个),并像对待任何其他字符串一样对待得到的字符串
注意:就像任何字符串一样,开始和结束引号之间的任何内容都是字符串的一部分,所以这个示例有一个前导空格(@root45指出了这一点)。该字符串还将包含空白和换行。
例如,:
1 2 3 | ' this is a very long string if I had the energy to type more and more ...' |
最后,还可以用Python像这样构造长行:
1 2 3 4 | s = ("this is a very" "long string too" "for sure ..." ) |
这将不包括任何额外的空格或换行(这是一个故意的例子,显示了跳过空格的效果):
1 | 'this is a verylong string toofor sure ...' |
不需要逗号,只需将要连接在一起的字符串放入一对圆括号中,并确保有任何需要的空格和换行。
如果你不想要多行字符串,而只想要一个长单行字符串,你可以使用圆括号,只要确保字符串段之间不包含逗号,那么它就是一个元组。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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) |
在您正在构造的SQL语句中,多行字符串也可以。但是,如果多行字符串中包含的额外空格有问题,那么这将是实现您想要的效果的好方法。
1 2 3 4 | longStr ="This is a very long string" \ "that I wrote to help somebody" \ "who had a question about" \ "writing long strings in Python" |
我发现自己对这个很满意:
1 2 3 4 5 6 | string ="""This is a very long string, containing commas, that I split up for readability""".replace(' ',' ') |
我发现,当构建长字符串时,您通常在做类似于构建SQL查询的事情,在这种情况下,这是最好的:
1 2 3 4 5 | query = ' '.join(( # note double parens, join() takes an iterable "SELECT foo", "FROM bar", "WHERE baz", )) |
Levon的建议很好,但可能容易出错:
1 2 3 4 5 6 7 | query = ( "SELECT foo" "FROM bar" "WHERE baz" ) query =="SELECT fooFROM barWHERE baz" # probably not what you want |
你也可以连接变量时,使用""符号:
1 2 3 4 5 6 | foo = '1234' long_string ="""fosdl a sdlfklaskdf as as df ajsdfj asdfa sld a sdf alsdfl alsdfl""" + foo +""" aks asdkfkasdk fak""" |
EDIT:找到一个更好的方法,使用名为params和.format():
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | body =""" <html> <head> </head> <body> <p> Lorem ipsum. </p> <dl> <dt>Asdf:</dt> <dd>{name}</dd> </dl> </body> </html> """.format( link='http://www.asdf.com', name='Asdf', ) print(body) |
在Python >= 3.6中,可以使用格式化字符串文字(f字符串)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | 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}''' |
这种方法使用:
只有一个反斜杠来避免初始换行符使用三重引号的字符串几乎没有内部标点符号使用textwrap在我看来,这种方式最像蟒蛇。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | # 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}''' ) |
更新:1/29/2019采纳@ShadowRanger使用
例如:
1 2 3 4 5 6 7 | 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' |
如果条件的值应该是字符串,您可以这样做:
1 2 3 4 5 6 7 | 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'" |
我发现
1 2 3 4 5 6 7 | def create_snippet(): code_snippet = textwrap.dedent("""\ int main(int argc, char* argv[]) { return 0; } """) do_something(code_snippet) |
我个人认为以下是用Python编写原始SQL查询的最佳方法(简单、安全、符合Python风格),特别是在使用Python的sqlite3模块时:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 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 |
优点
简洁而简单的代码(python的!)避免SQL注入兼容Python 2和Python 3(毕竟它是Python风格的)不需要字符串连接不需要确保每一行最右边的字符都是空格
缺点
由于查询中的变量被
我通常这样用:
1 2 3 4 5 | text = ''' This string was typed to be a demo on how could we write a multi-line text in Python. ''' |
如果你想删除每一行中烦人的空格,你可以这样做:
1 2 | text = ' '.join(line.lstrip() for line in text.splitlines()) |
您实际的代码不应该工作,您丢失了"行"末尾的空格(例如:
多行字符串有三重引号:
1 2 3 | string ="""line line2 line3""" |
它将包含换行符和额外的空格,但对于SQL来说这不是问题。
"ala"Scala方式(但我认为是OQ要求的最python化的方式):
1 2 3 4 5 6 7 8 9 10 11 | 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(' | ',' ').replace(' | ',' ') |
如果你想要没有跳线的final str,只需在第二个replace的第一个参数的开头加上
1 2 | .replace(' | ',' ')`. |
注意:"…templates."和"Also,…"之间的白线需要
您还可以将sql语句放在一个单独的文件
1 2 | with open('action.sql') as f: query = f.read() |
因此sql语句将从python代码中分离出来。如果sql语句中有需要用python填充的参数,可以使用字符串形式(如%s或{field})
我使用递归函数来构建复杂的SQL查询。这种技术通常可用于构建大型字符串,同时保持代码的可读性。
1 2 3 4 5 6 7 8 9 | # 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:如果需要的话,看看强大的python-sqlparse库来打印漂亮的SQL查询。http://sqlparse.readthedocs.org/en/latest/api/#sqlparse.format
另一个选项,我认为当代码(e。g变量)缩进,输出字符串应该是一行(没有换行):
1 2 3 4 5 6 7 8 9 10 11 12 | def some_method(): long_string =""" a presumptuous long string which looks a bit nicer in a text editor when written over multiple lines """.strip(' ').replace(' ', ' ') return long_string |
我喜欢这种方法,因为它赋予阅读特权。在我们有长字符串的情况下是没有办法的!取决于缩进的级别,你仍然被限制在每行80个字符…嗯…不用再说什么了。在我看来,python风格指南仍然非常模糊。我采用@Eero Aaltonen方法,因为它赋予阅读和常识以特权。我明白,风格指南应该帮助我们,而不是让我们的生活一团糟。谢谢!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 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 ) """ |
通常,对于多行注释/字符串,我使用
1 2 3 4 5 6 7 8 9 10 | 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) |
您可以使用任何字符串来连接所有列表元素,比如"
干杯! !