在python插值中检测与命名占位符混合的%s

时间:2012-01-09 22:54:28

标签: python string-interpolation

显然,Python将允许

'%s %(var)s' % {'var': 'x'}

产生

"{'var': 'x'} x"

我正在写一些我基本上只想要python的命名占位符替换功能的东西。有没有办法检测命名和位置占位符的混合?

编辑:这个背景是我写的是一种模板工具。在写了一堆含有%(named)s的东西之后,然后调用template.substitute(dict)去替换所有东西。我试图阻止人们在字符串中留下%[srfd,etc]的情况(因为他们忘记插入或其他东西),如果它被留在那里就会抛出错误。

3 个答案:

答案 0 :(得分:4)

str .__ mod __ 内置函数不可重新编程。没有办法有选择地关闭它的一些功能。

然而,您可以使用正则表达式来定位位置占位符并在字符串插值之前将其转义:

>>> d = {'var': 'x'}
>>> template = '%s %(var)s'
>>> esc_template = re.sub(r'(%[^()]*[sdf])', r'%\1', template)
>>> esc_template % d
'%s x'

答案 1 :(得分:2)

如果Raymond Hettinger告诉你它是如何完成的,你会倾听,因为他是对的:)

另一个选择是子类string.Template来定义你自己的替换逻辑和语法。

答案 2 :(得分:2)

不是即时修复选项,但是要扩展agander的评论,使用str.format至少可以保证您不会在没有看到错误的情况下意外填写任何未命名的占位符。这是因为它通过使用适当的方法调用语法将位置替换与命名的替换分开:

>>> '%s %(var)s' % {'var': 'x'}
"{'var': 'x'} x"
>>> '{} {var}'.format(var='x')

Traceback (most recent call last):
  File "<pyshell#3>", line 1, in <module>
    '{} {var}'.format(var='x')
IndexError: tuple index out of range
>>> '{} {var}'.format(8, var='x')
'8 x'

我经常使用Python支持两种不同的替换语法,但它有点滥用特征性。由于我编写了大量代码组装SQL查询以传递给数据库接口的代码,后者使用%s作为参数化查询的占位符,我使用str.format进行所有外层查询粘贴,这样就离开了%s占位符完全不受干扰,无需不断逃脱它们。

>>> '%s {var}'.format(var='x')
'%s x'

如果这是您希望在输出中传递%s的原因,str.format可以简化您的生活。