2

显然,Python 将允许

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

产生

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

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

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

4

3 回答 3

4

str.__mod__内置函数不可重新编程。没有办法选择性地关闭其某些功能。

但是,您可以使用正则表达式来定位位置占位符并在字符串插值之前对其进行转义:

>>> d = {'var': 'x'}
>>> template = '%s %(var)s'
>>> esc_template = re.sub(r'(%[^()]*[sdf])', r'%\1', template)
>>> esc_template % d
'%s x'
于 2012-01-09T23:01:23.817 回答
2

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

另一种选择是子类化string.Template以定义您自己的替换逻辑和语法。

于 2012-01-09T23:08:29.770 回答
2

不是即时修复选项,但为了扩展 agander 的评论, usingstr.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就是您希望在输出中传递 s的原因,那么str.format可以大大简化您的生活。

于 2012-01-09T23:21:26.033 回答