为字符串格式添加自定义转换类型

时间:2013-11-08 16:46:09

标签: python printf string-formatting

在python中是否还有其他转换类型添加到字符串格式?

基于%的字符串格式化中使用的标准转换类型类似于字符串s,小数点d等等。我想要做的是添加一个新的我可以指定一个自定义处理程序(例如lambda函数)的字符,它将返回要插入的字符串。

例如,我想添加h作为转换类型,以指定应转义字符串以便在HTML中使用。举个例子:

#!/usr/bin/python

print "<title>%(TITLE)h</title>" % {"TITLE": "Proof that 12 < 6"}

这会在cgi.escape上使用"TITLE"来生成以下输出:

<title>Proof that 12 &lt; 6</title>

3 个答案:

答案 0 :(得分:14)

您可以为html模板创建自定义格式化程序:

import string, cgi

class Template(string.Formatter):
    def format_field(self, value, spec):
        if spec.endswith('h'):
            value = cgi.escape(value)
            spec = spec[:-1] + 's'
        return super(Template, self).format_field(value, spec)

print Template().format('{0:h} {1:d}', "<hello>", 123)

请注意,与Martijn的答案不同,所有转换都发生在模板类中,不需要更改输入数据。

答案 1 :(得分:8)

不使用%格式,不,不可扩展。

使用为format string syntaxstr.format()定义的较新format()时,您可以指定不同的格式选项。自定义类型可以实现__format__()方法,并且将使用模板字符串中使用的格式规范调用:

import cgi

class HTMLEscapedString(unicode):
    def __format__(self, spec):
        value = unicode(self)
        if spec.endswith('h'):
            value = cgi.escape(value)
            spec = spec[:-1] + 's'
        return format(value, spec)

确实要求您为字符串使用自定义类型:

>>> title = HTMLEscapedString(u'Proof that 12 < 6')
>>> print "<title>{:h}</title>".format(title)
<title>Proof that 12 &lt; 6</title>

对于大多数情况,只需在将字符串交给模板之前格式化字符串,或者使用专用的HTML模板库(如Chameleon,Mako或Jinja2);这些处理HTML转义。

答案 2 :(得分:2)

我参加聚会有点晚了,但根据https://mail.python.org/pipermail/python-ideas/2011-March/009426.html

中的想法,我的工作就是这么做的
>>> import string, cgi
>>> from xml.sax.saxutils import quoteattr
>>> class MyFormatter(string.Formatter):
    def convert_field(self, value, conversion, _entities={'"': '&quot;'}):
        if 'Q' == conversion:
            return quoteattr(value, _entities)
        else:
            return super(MyFormatter, self).convert_field(value, conversion)

>>> fmt = MyFormatter().format
>>> fmt('{0!Q}', '<hello> "world"')
'"&lt;hello&gt; &quot;world&quot;"'