我知道可以扩展Formatter以提供PEP3101中讨论的其他演示类型,但这对我的需求来说太慢了。我很好奇为注入字符串的自定义表示类型可能会有哪些其他选项。
目前,唯一想到的其他选项是检查字符串的{vars},记下表示类型和索引,删除自定义表示类型,格式,然后根据我的需要格式化结果。
在利用格式速度的同时还有其他选项可以避免后期处理吗?
答案 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('<', '<').replace('>', '>')
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><asdf'
在* args和** kwargs上的fmt函数内部会发生对uobj的转换。还有一些细节需要解决,例如我注意到我的单元测试无法解析,并且uobj需要通过* uobj和** uobj解压缩才能按需转换对象,尽管我可能需要将其分解为列表和字典的相应克隆。不过,这对我来说似乎是最好的选择。
修改强>
似乎很难在这里阅读模拟容器类型 http://docs.python.org/reference/datamodel.html#emulating-container-types