1

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

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

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

4

1 回答 1

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 的强制转换。这里还有更多细节需要解决,例如我注意到 ints 在我的单元测试中无法解析,并且 uobj 需要通过 *uobj 和 **uobj 解包才能按需转换对象,尽管我可能需要将其分解为列表和字典的相应克隆。不过,这对我来说似乎是最好的道路。

编辑

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

于 2011-12-22T06:48:20.027 回答