Python / Cython自定义格式化程序字符串表示类型

时间:2011-12-21 15:30:07

标签: python cython formatter

我知道可以扩展Formatter以提供PEP3101中讨论的其他演示类型,但这对我的需求来说太慢了。我很好奇为注入字符串的自定义表示类型可能会有哪些其他选项。

目前,唯一想到的其他选项是检查字符串的{vars},记下表示类型和索引,删除自定义表示类型,格式,然后根据我的需要格式化结果。

在利用格式速度的同时还有其他选项可以避免后期处理吗?

1 个答案:

答案 0 :(得分:1)

我制定了一个似乎在cython中的开销明显较少的解决方案,尽管在python中可以做同样的事情并且在这里提供示例(不确定开销)。

根据python文档,对象可以实现__ format__方法并接收格式规范。在cython中我实现了我自己的uobj类型,它作为传递给str.format的args和kwargs的泛型。 python中的相同内容(作为转义<和>的一般示例)看起来像这样。

class uobj:
    def __init__(self, obj):
        self.obj = obj
    def __format__(self, format_spec):
        if format_spec == 's':
            return str(self.obj)
        else:
            # edit, shoehorning this in for completeness
            # to call an original format spec as should probably
            # happen after you do your own processing, use __format__
            if isinstance(self.obj, (int, float)):
                return self.obj.__format__(format_spec)
                # so then a :.2f spec on uobj(123.456) would work as expected
            return str(self.obj).replace('<', '&lt;').replace('>', '&gt;')
    def __getitem__(self, key):
        return uobj(self.obj[key])

现在,uobj可以存储用户对象(以下示例中的str或dict)然后可以像

一样访问
d = uobj({'a': '<b>asdf'})
s = uobj('<span>qwer</span>')
'{0:s} {d[a]}'.format(s, d=d)

# ouputs: '<span>qwer</span>&lt;asdf'

在* args和** kwargs上的fmt函数内部会发生对uobj的转换。还有一些细节需要解决,例如我注意到我的单元测试无法解析,并且uobj需要通过* uobj和** uobj解压缩才能按需转换对象,尽管我可能需要将其分解为列表和字典的相应克隆。不过,这对我来说似乎是最好的选择。

修改

似乎很难在这里阅读模拟容器类型 http://docs.python.org/reference/datamodel.html#emulating-container-types