使用 python 动态格式化元组元组中的字符串

dynamic format the string from tuples of tuple using python

在下面,场景 1 在两个(代码 1 和代码 2)中都运行良好。但是场景 2 在代码 1 中不起作用。

我的要求是 Tuple 应该不断自我重复,直到它动态地填充查询中的所有格式字符串。因为 where 子句对于所有查询都不是常量。

场景一#

query = SELECT * FROM test.order where total_price in {}

元组:

finTup=((125, 125, 125, 125),)
SELECT * FROM test.order where total_price in (125, 125, 125, 125)

场景2#

query = SELECT * FROM test.order WHERE order_id IN {} AND product_id IN {}

元组:

finTup=((101, 105, 106, 107), (2, 2, 2, 2))

代码 1:

frt = 'finTup[{}]'
half = ''
val = ''
i = 0
le = len(finTup)
for i in range(le):
    print(i)
    print(eval(frt.format(i)))
    if i == le -1:
        half = half + frt.format(i)
        val = val + " " + frt.format(i)
    else:
        half = half + frt.format(i)+', '
        val = val + " " + frt.format(i)+', '
temp2 = query.format(eval(val))

代码2:

if le == 1:
     query = query.format(finTup[0])
elif le == 2:
      query = query.format(finTup[0], finTup[1])
 elif le == 3:
       query = query.format(finTup[0], finTup[1], finTup[2])
elif le == 4:
       query = query.format(finTup[0], finTup[1], finTup[2], finTup[3])

Error:
temp2 = query.format(eval(val))
IndexError: tuple index out of range

请帮我解决这个问题。

TL;DR

您好,您遇到此错误是因为您试图向需要两个参数的 format 函数提供单个参数(因为您有 2 个 {})。

注意:避免使用eval函数...这是非常不推荐的,在你目前的情况下更不推荐。无需评估 str.

即可完成所有操作

接下来,我只运行场景#2的代码,即

query2 = """SELECT * FROM test.order WHERE order_id IN {} AND product_id IN {}"""
finTup = ((101, 105, 106, 107), (2, 2, 2, 2))

第 1 步:调试

假设您按如下方式更新调试代码:

frt = 'finTup[{}]'
half = ''
val = ''
i = 0 # btw, you don't need to initialize i here
le = len(finTup)

for i in range(le):
    if i == le -1:
        half = half + frt.format(i)
        val = val + " " + frt.format(i)
    else:
        half = half + frt.format(i)+', '
        val = val + " " + frt.format(i)+', '

print val
print eval(val)

temp2 = query.format(eval(val))

你的输出应该是:

 vars[0],  vars[1]
((101, 105, 106, 107), (2, 2, 2, 2))

所以,假设您根据上面的输出编写 python 代码,您会做的是:

query.format(((101, 105, 106, 107), (2, 2, 2, 2)))

您实际上提供了一个具有两个元素的 tuple 类型的参数。但这里重要的是,您为 format 提供 单个参数 format 函数将尝试访问您未提供的第二个参数。坏了。


第 2 步:修复代码

看看这个 SO article。它向您展示了如何使用 * 运算符。它基本上将 listtuple 转换为一系列项目。非常适合函数参数等。

因此,应用于您当前的案例:

temp2 = query.format(*eval(val))

技巧就完成了。


第 3 步:优化

现在,让我们扔掉 代码 1,并使用我们在 代码 2 中学到的知识。我们需要将 tupletuple 解压为参数以提供给 format。那么,为什么不只是做:

# I renamed `finTup` to `vars` since I don't know what it means
def get_query(query, vars):
    return query.format(*vars)

它基本上将代码1代码2的逻辑组合成一行