9

在 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>
4

3 回答 3

17

您可以为 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)

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

于 2013-11-08T17:12:40.567 回答
9

不是%格式化,不,那是不可扩展的。

使用为和定义的较新格式字符串语法时,您可以指定不同的格式选项。自定义类型可以实现一个方法,该方法将使用模板字符串中使用的格式规范调用:str.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 转义。

于 2013-11-08T16:54:38.150 回答
4

我参加聚会有点晚了,但这就是我所做的,基于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;"'
于 2015-12-10T13:41:39.763 回答