【问题标题】:What is a pythonic way to find and replace format parameters?什么是查找和替换格式参数的pythonic方法?
【发布时间】:2021-09-24 20:33:31
【问题描述】:

给定一个带有绑定的字符串:

input = "SELECT * FROM table WHERE col1 = %s AND col2 = %(col2_value)s"

我想将%s 转换为?%(named)s 转换为@named,这样我得到:

input = "SELECT * FROM table WHERE col1 = ? AND col2 = @col2_value"

我当前的实现使用re 交换两种类型并返回绑定列表:

def _convert_bindings(query: str) -> Tuple[str, List[Union[None, str]]]:
    pos_rex = r"%s"
    named_rex = r"%\((\w+)\)s"
    bindings = [
        None if m.string == "%s" else re.search(r"%\((?P<name>\w+)\)s", m.string).group("name")
        for m in re.finditer(f"{pos_rex}|{named_rex}", query)
    ]
    sql = re.sub(pos_rex, r"?", query)
    sql = re.sub(named_rex, r"@\1", query)

    return sql, bindings

但我认为 Python 必须有一个内置的方法来查找和替换参数,因为 str.format 已经这样做了。

那么提取%s%(named)s 并随后替换它们的最pythonic 方法是什么?是否有一个函数/属性可以命名为“str.params”或内置模块中的函数 getparams?

假设没有命名参数列表的先验知识。

【问题讨论】:

  • 请问您为什么要这样做?您是否正在从一个数据库后端切换到另一个?
  • 对于你所描述的,这个解决方案似乎很好。任何使代码“更加pythonic”的修改都可能不会提高这里的性能。您已经有了列表理解,其余代码只是使用正则表达式模块,所以我认为这很好。
  • 我同意使用变量绑定,但如果您在代码库中有问题的字符串格式查询,我认为这是一个手动重构工作来完成并修复所有这些查询。或者你的用例是什么?
  • @Tim Roberts + Robert:我在代码中使用 psycopg2 和本机绑定,并在测试中使用 pglast 解析 SQL 以确保查询预期的源表。 pglast 不支持原生绑定,只支持 PG 绑定。

标签: python replace


【解决方案1】:
p = re.compile("%\(([^)]*)\)s")

input = "SELECT * FROM table WHERE col1 = %s AND col2 = %(col2_value)s"

query = input.replace("%s", "?")
query = p.sub(r"@\1" , query)
  
print(query)

# SELECT * FROM table WHERE col1 = ? AND col2 = @col2_value

【讨论】:

  • 你能解释一下为什么这比问题中显示的代码更 Pythonic 吗?
  • @mkrieger1 它只是在设计方面更加 Pythonic,因为它更易于维护,并且尽可能易于阅读/理解。在不需要迭代的情况下使用迭代“手动”做事是典型的 Pythonic 反模式。 The Zen of Python
  • 编辑:这个解决方案也将快得多,因为模式被编译和持久化,而不是在原始中使用三参数re.sub 方法。
  • re 模块应该自动缓存已编译的模式。
  • It doesn't。您必须编译表达式并重用结果以进行缓存。 A real-world example of this 显示速度提高了 30%。
猜你喜欢
  • 1970-01-01
  • 2012-05-02
  • 1970-01-01
  • 1970-01-01
  • 2012-07-20
  • 2012-12-05
  • 1970-01-01
  • 2019-06-28
  • 1970-01-01
相关资源
最近更新 更多