在python中如何递归替换字符串中的%占位符

时间:2018-06-15 16:04:32

标签: python-2.7

我有一大块python代码,用于构建SQL查询。它通过调用几个其他函数来获取查询的一部分,然后组装它们。我试图弄清楚如何输出一个实际运行的MySQL查询字符串。

我不想显示所有实际代码(因为它有很多代码),而且我也不太了解python,但这是我试图展示这段代码的作用:

import random

def myClause():
  if (random.randint(1,101) > 50):
    clause_part = 10;
  else
    clause_part = 500;
  clause = "WHERE table2.id > %(clause_part)s
  return clause

def doQuery():
  clause = myClause();
  if (random.randint(1,101) > 50):
    other_clause_part = 10;
  else
    other_clause_part = 500;
  my_sql = """SELECT * FROM table1 JOIN table2 ON table1.t2_id = table2.id
     WHERE table1.id > %(other_clause_part)s
     %(clause)s""" % {'other_clause_part': other_clause_part,
                      'clause': clause}

  print(my_sql)
  cur.execute(my_sql)

它是这样的(是的,我知道,我确定在这段代码中存在某种python错误,再次,我不知道python)。正在发生的事情是当我看到打印出的结果时,它只评估' other_clause_part'并且不评估'条款'。我认为这是因为被替换的占位符只有一层深。换句话说,我有占位符,我也有占位符,他们自己有占位符。有没有办法以递归方式替换字符串中的所有占位符,然后在某处打印出输出?

1 个答案:

答案 0 :(得分:1)

所以,首先我必须学习更多python并让我的例子真正起作用。这使我得到以下结论:

import random

def myClause():
  if (random.randint(1,101) > 50):
    clause_part = 10
  else:
    clause_part = 500
  clause = "WHERE table2.id > %(clause_part)s"
  return clause

def doQuery():
  clause = myClause()
  if (random.randint(1,101) > 50):
    other_clause_part = 10
  else:
    other_clause_part = 500
  my_sql = """SELECT * FROM table1 JOIN table2 ON table1.t2_id = table2.id
    WHERE table1.id > 1 %(other_clause_part)s
    %(clause)s""" % {'other_clause_part': other_clause_part,
                     'clause': clause}

  my_sql2 = my_sql % {'clause_part': 'whatever'}

  print(my_sql2)

doQuery()

我尝试做的原始事情是不可能的,因为第一个字符串中的占位符被另一个占位符替换。第二个字符串的占位符也不在用于替换占位符的数据对象中。 (对不起,这听起来不对,所以我会用例子解释)第一次替换后,我的字符串看起来像这样:

SELECT * FROM table1 JOIN table2 ON table1.t2_id = table2.id
    WHERE table1.id > 1 500
    WHERE table2.id > %(clause_part)s

现在,如果你看一下这个,你会发现在doQuery函数中我从未定义过'clause_part'。这是在myClause函数中定义的,但在返回值之前从未实际应用于字符串作为替换。

那么作为一个测试,我只是放入另一个替换字符串('what'),现在我可以看到如果你有某种元组数组,你可以做一个循环或诸如此类的东西,并“递归地”替换所有的它们。

另一方面,如果你只是想解决我面临的原始实际问题(试图弄清楚查询的样子),你可以这样做:

print(cur._last_executed)

抱歉浪费你所有的时间。也许有人会觉得这很有帮助。