Pythonic方式创build一个长的多行string
我有一个很长的查询。 我想在Python中分成几行。 在JavaScript中使用的方法是使用几个句子,并将它们与一个+
运算符(我知道,也许这不是最有效的方式),但我并不在乎这个阶段的性能,只是代码的可读性)。 例:
var long_string = 'some text not important. just garbage to' + 'illustrate my example';
我尝试了在Python中做类似的事情,但它没有工作,所以我用\
来拆分长string。 但是,我不确定这是否是唯一的/最好的/ pythonicest的方式。 看起来很尴尬。 实际代码:
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
你在说多线串吗? 很简单,使用三重引号开始和结束它们。
s = """ this is a very long string if I had the energy to type more and more ..."""
你也可以使用单引号(当然在开始和结束时,其中的3个),并像处理其他string一样处理结果string。
注意 :正如任何string一样,起始和结束引号之间的任何内容都成为string的一部分,所以这个例子有一个前导空白(正如@ root45指出的那样)。 这个string也将包含空白和换行符。
IE中:
' this is a very\n long string if I had the\n energy to type more and more ...'
最后,还可以像这样在Python中构build长行:
s = ("this is a very" "long string too" "for sure ..." )
这将不包括任何额外的空白或换行符(这是一个故意的例子,显示了跳过空白的效果):
'this is a verylong string toofor sure ...'
不需要逗号,只需将要连接的string放在一对括号中,并确保logging任何所需的空格和换行符。
如果你不需要多行string,但是只有一个长的单行string,你可以使用圆括号,只要确保在string段之间不包含逗号,那么它就是一个元组。
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语句中,多行string也可以。 但是,如果多行string所包含的多余的空格是一个问题,那么这将是一个很好的方法来实现你想要的。
打破\
线为我工作。 这里是一个例子:
longStr = "This is a very long string " \ "that I wrote to help somebody " \ "who had a question about " \ "writing long strings in Python"
我发现自己对这个很满意:
string = """This is a very long string, containing commas, that I split up for readability""".replace('\n',' ')
我发现在构build长string的时候,通常要做的就是构build一个SQL查询,在这种情况下,这是最好的:
query = ' '.join(( # note double parens, join() takes an iterable "SELECT foo", "FROM bar", "WHERE baz", ))
Levon提出的build议是好的,但可能容易出错:
query = ( "SELECT foo" "FROM bar" "WHERE baz" ) query == "SELECT fooFROM barWHERE baz" # probably not what you want
在使用“”“符号时,您还可以连接variables:
foo = '1234' long_string = """fosdl a sdlfklaskdf as as df ajsdfj asdfa sld a sdf alsdfl alsdfl """ + foo + """ aks asdkfkasdk fak"""
编辑:find一个更好的方法,与命名参数和.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)
在Python> = 3.6中,您可以使用格式化string文字(fstring)
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}'''
例如:
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'
如果条件的值应该是一个string,你可以这样做:
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'"
你的实际代码不能工作,你在“行”结尾缺less空格(例如: role.descr as roleFROM...
)
有多行string的三元引用:
string = """line line2 line3"""
它将包含换行符和额外的空格,但对于SQL来说这不是问题。
你也可以把sql语句放在一个单独的文件action.sql
并将其加载到py文件中
with open('action.sql') as f: query = f.read()
所以sql语句将从python代码中分离出来。 如果在sql语句中有需要从python填充的参数,可以使用string格式化(如%s或{field})
我使用recursion函数来构build复杂的SQL查询。 这种技术通常可以用来构build大的string,同时保持代码的可读性。
# 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)
PS:看看真棒python-sqlparse库来漂亮打印SQL查询,如果需要的话。 http://sqlparse.readthedocs.org/en/latest/api/#sqlparse.format
另一种select,我认为更可读的代码(如variables)缩进和输出string应该是一个class轮(没有换行符):
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
“拉拉” 斯卡拉的方式(但我认为是OQ要求最pythonic的方式):
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(' | ',' ')
如果你想最后str没有跳转线,只需在第二个replace的第一个参数的开始处放置\n
:
.replace('\n | ',' ')`.
注意:“…模板”之间的白线。 和“另外,…”在|
之后需要空格 。
我喜欢这种方式,因为它特权阅读。 如果我们有很长的琴弦,那就没办法了! 根据您所使用的缩进级别,每行只能有80个字符。呃…不需要说别的。 在我看来,Python风格指南仍然非常模糊。 我采取了@Eero Aaltonen方法,因为它具有阅读和常识的特权。 我明白,风格指南应该帮助我们,而不是让我们的生活一团糟。 谢谢! 请给出意见!
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 ) """
我个人发现以下是Python中编写原始SQL查询的最好方法(简单,安全和Pythonic),特别是在使用Python的sqlite3模块时 :
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
优点
- 简洁的代码(Pythonic!)
- 从SQL注入安全
- 兼容Python 2和Python 3(毕竟它是Pythonic)
- 不需要string连接
- 不需要确保每行的最右侧字符是一个空格
缺点
- 由于查询中的variables被replace为
?
占位符,可能会有点难以跟踪哪些?
是在查询中有很多Pythonvariables被replace。