2012-01-09 18 views
2

因此很明显,Python将允许检测%s与在python插值命名占位符混合

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

产生

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

我写的东西,我基本上要Python的命名占位符代替才有的功能。有什么方法可以检测到名称和位置占位符的组合吗?

编辑:这样的背景是,我写的东西,是那种一个模板工具。在遍布各处写入了一大堆%(已命名)的东西之后,然后调用template.substitute(dict)去替换所有内容。我试图避免的情况下,人们在字符串中留下%[srfd,etc](因为他们忘了插或某物),如果它已经离开了那里抛出一个错误。

+0

这并没有真正回答你的问题,但对新代码的建议是使用['str.format'(http://docs.python.org/library/stdtypes.html#str.format)而不是'%s'语法。 – aganders3 2012-01-09 22:59:00

+0

你能否用'%% s'替换'%s'? – 2012-01-09 23:00:13

+0

@ aganders3最终可能这样做,代码中有相当位虽然 – nik3daz 2012-01-09 23:02:06

回答

4

海峡.__ mod__内建函数不是可重新编程的。没有办法有选择地关闭其某些功能。

您可以但是使用正则表达式来定位的位置占位符和之前逃脱他们的字符串插值:

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

如果雷蒙德赫廷杰告诉你它是如何做,你听着,因为他是正确的:)

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

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查询传递到DB接口,它使用%s的占位符参数化查询,我做str.format我所有的外层查询粘贴,这让该%s占位符完全不受干扰,而不必不断逃避他们。

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

如果这是你有你期望得到通过您的输出通过%s真正的原因,str.format可以简化你的生活了很多。