Python中的链式字符串格式
在处理一点SQL格式时,我惊奇地发现我可以链接字符串格式化程序:Python中的链式字符串格式,python,string,Python,String,在处理一点SQL格式时,我惊奇地发现我可以链接字符串格式化程序: def get_sql(table, limit=True): sql = "select report_date from %s" if limit: result = "%s limit 1" % sql % table else: result = sql % table return result 这合法吗?有什么理由不这样做吗 这是完全合法的 字符串格式化
def get_sql(table, limit=True):
sql = "select report_date from %s"
if limit:
result = "%s limit 1" % sql % table
else:
result = sql % table
return result
这合法吗?有什么理由不这样做吗 这是完全合法的
字符串格式化程序的“”形式实际上是一个特例-对于多个项,通常使用元组,这将导致一个更明显的示例,说明为什么它是正确的
result = "%s limit 1" % (sql % (table,),)
这本书最初是为了鼓励提问者支持多种格式是一种合法的语言功能,但正如Nas Banov所评论的那样,它读起来确实像是我在解释它是如何工作的(而不是通过搞错代码)。它不会像这样从右向左构建字符串,但必须从左向右构建(关联)。运算符必须在左侧获取字符串并返回一个,但可以在右侧获取非字符串(元组)。由于不能在一对元组上使用%,因此它不可能反向工作
然而,它可能会导致复杂/混乱的代码,所以我个人会非常谨慎地使用它
你可以这样做:
def get_sql(table, limit=True):
sql = "select report_date from"
strlimit = ""
if limit:
strlimit = "limit 1"
return "%s %s"%(sql, strlimit)
In [49]: "%s limit 1" % sql
Out[49]: 'select report_date from %s limit 1'
In [50]: "%s limit 1" % sql % 'table'
Out[50]: 'select report_date from table limit 1'
它之所以有效,是因为这样的陈述:
def get_sql(table, limit=True):
sql = "select report_date from"
strlimit = ""
if limit:
strlimit = "limit 1"
return "%s %s"%(sql, strlimit)
In [49]: "%s limit 1" % sql
Out[49]: 'select report_date from %s limit 1'
In [50]: "%s limit 1" % sql % 'table'
Out[50]: 'select report_date from table limit 1'
“此处有一些值%s”%value
实际上返回一个字符串。这样看可能更符合逻辑:
def get_sql(table, limit=True):
sql = "select report_date from"
strlimit = ""
if limit:
strlimit = "limit 1"
return "%s %s"%(sql, strlimit)
In [49]: "%s limit 1" % sql
Out[49]: 'select report_date from %s limit 1'
In [50]: "%s limit 1" % sql % 'table'
Out[50]: 'select report_date from table limit 1'
result=(%s限制1”%sql)%table
这样做并没有什么明显的错误,但链接操作符可能会导致在找出错误来源时出现问题
例如,这很好:
>>> sql = 'a value of %s'
>>> x = 'some string %s with stuff'
>>> y = 'VALUE'
>>> x % sql % y
'some string a value of VALUE with stuff'
但是,如果其中存在格式错误(我知道这个示例是病态的,但它能让人理解这一点):
sql='a value of%d'
>>>x='某个字符串%d包含内容'
>>>y=123
>>>x%sql%y
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
类型错误:%d格式:需要数字,而不是str
确实不清楚是哪个%d
导致了您的错误。出于这个原因,我会将其拆分,如果可能的话,每行只使用一个%
格式化程序,因为这样回溯将能够准确地指出哪一行和哪一个格式化程序有问题
作为记录,通过每行使用一个格式化程序,您还可以让其他需要阅读您的代码并尝试了解发生了什么的人的生活变得更加轻松。我将这样写:
def get_sql(table,limit=True):
sql = "select report_date from %s"%table
if limit: sql += " limit 1"
return sql
注:您发布的代码如下所示:
def get_sql(table, limit=True):
sql = "select report_date from"
strlimit = ""
if limit:
strlimit = "limit 1"
return "%s %s"%(sql, strlimit)
In [49]: "%s limit 1" % sql
Out[49]: 'select report_date from %s limit 1'
In [50]: "%s limit 1" % sql % 'table'
Out[50]: 'select report_date from table limit 1'
当然你能做到,但我不认为这一点特别清楚。为什么是的,可以像那样链接%字符串格式,即使这是我第一次看到它被使用(请注意,这是一种可怕的方式)
原因是同一类型的运算符从左到右分组(具有“左关联性”-除了求幂
**
和比较a--
:错误的解释,这与多个参数无关,关联性是错误的。请尝试%ss限制1”“%”“%”“%”BOO“
要理解我的意思,只要我们按照您的建议插入括号,%ss limit 1%”(“%”“%”('BOO'),这个表达式就会起作用
breaks/error。此外,您提出的修复方案并不比您误解的原始方案好多少。我并不是说它与参数的单数或多重性有关,只是如果您从使用单元组改为使用元组,它将更清楚地表明这是一件合法的事情。您的反例是错误的-(“%”(“'BOO'))无效。“%s limit 1%”“%s“%”BOO“
与“%s limit 1%”(“%s“%”('BOO')相比)
。这两种方法都有效。请注意,问题不包含示例所需的%ss
格式。这不是“建议的修复”-原始代码没有问题,只是建议的更改。似乎您不明白。(a)按您所做的方式放置括号会更改操作顺序。当您有A%B%C
类型的表达式时,它将作为(A%B)%C
执行,而不是作为A%(B%C)
,因为您的第一组参数会强制执行它。(B)另外,您的理解是放置()around表达式使元组脱离它是错误的-事实并非如此。要强制元组,您必须显式使用构造函数tuple()
,或者使用“愚蠢的逗号”,例如%s limit 1%(sql%(表,),)
——这将创建元组,但您的示例仍然是错误的,因为(a)是的,你说得很对。我昨天离开办公桌后才意识到我把元组搞砸了,这让我说的话很不清楚。威尔会修正答案。操作的顺序并不说明为什么它是/不是支持tho的有效语言功能。哈哈,为什么你甚至需要使用%formatting?;-)(不过比原来的要好得多)