模板字符串中的eval

时间:2012-05-28 22:50:03

标签: string templates python

我正在考虑将一个相当笨重的bash脚本移植到python但我仍然坚持如何处理以下方面:脚本的要点是根据动态获取的数据生成png图像。 bash脚本抓取数据,并构建一个很长的convert实用程序调用,有很多选项。似乎python的模板字符串将是一个很好的解决方案(我非常希望保留在标准库中,因为我将部署到共享主机),但我发现你无法在bash中评估表达式:

>>> from string import Template
>>> s = Template('The width times one is ${width}')
>>> s.substitute(width=45)
'The width times one is 45'
>>> t = Template('The width times two is ${width*2}')
>>> t.substitute(width=45)
# Raises ValueError

由于我的bash脚本在很大程度上依赖于这样的算法(否则要跟踪的变量数量将呈指数级增长)我想知道是否有一种方法可以在python中模拟这种行为。我看到this question,大致相同,有评论,阅读:

  

这将是非语言的,因为它违反直觉 - 字符串只是       字符串,他们不应该运行代码!

如果是这种情况,那么解决这个问题的更为惯用的方法是什么? 上面链接的问题的建议答案是使用%语法或format()函数的字符串格式,但我认为这不会适用于我的字符串中的变量数量(大约50)。

4 个答案:

答案 0 :(得分:2)

为什么不使用内置字符串格式?

width = 45
"Width times one is {width}".format(width=width)
"Width times two is {width}".format(width=2*width)

结果

Width times one is 45
Width times two is 90

答案 1 :(得分:2)

这个问题的Pythonic解决方案是忘记字符串格式化并将列表的参数传递给subprocess函数之一,例如

# I have no idea about convert's command line usage,
# so here's an example using echo.
subprocess.call(["echo", str(1 + 1), "bla"])

这样,就没有必要构建一个字符串,也不需要担心引用。

答案 2 :(得分:2)

您可能需要更好的模板引擎。 Jinja2支持这类内容以及更多内容。我不认为标准库有任何同样强大的功能,但从我的想法来看,该库是纯Python,所以你可以通过复制它将它集成到你的应用程序中。

如果Jinja由于某种原因不适合你,请查看具有a section specifically for those kinds of libraries的Python wiki。其中包括非常轻量级的Templite,它只是一个类,似乎完全符合你的需要。

答案 3 :(得分:2)

任务并不那么难,你为什么不做一些有趣的编码?这里的功能几乎可以满足您的需求。

import re
def TempEval(template,**kwargs):
    mark = re.compile('\${(.*?)}')
    for key in kwargs:
        exec('%s=%s'%(key,kwargs[key]))
    for item in mark.findall(template):
        template=template.replace('${%s}'%item,str(eval(item)))
    return template


print TempEval('The width times one is ${width}',width=5)
#The width times one is 5
print TempEval('The width times two is ${width*2}',width=5)
#The width times two is 10