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

bri*_*rns 7 python printf string-formatting

无论如何在python中添加额外的转换类型到字符串格式?

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

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

#!/usr/bin/python

print "<title>%(TITLE)h</title>" % {"TITLE": "Proof that 12 < 6"}
Run Code Online (Sandbox Code Playgroud)

这将使用cgi.escape"TITLE"生成以下的输出:

<title>Proof that 12 &lt; 6</title>
Run Code Online (Sandbox Code Playgroud)

geo*_*org 15

您可以为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)
Run Code Online (Sandbox Code Playgroud)

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

  • 请注意,“Formatter”类上还有一个更简单的“convert_field”方法,它处理格式字段转换,如内置的“!s”和“!r”。 (2认同)

Mar*_*ers 8

没有%格式化,不,那是不可扩展的.

可以使用较新时指定不同的格式选项格式字符串语法的定义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)
Run Code Online (Sandbox Code Playgroud)

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

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

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