Я разработал решение, которое, по-видимому, значительно меньше накладных расходов на cython, хотя то же самое можно сделать и в python, и плохой пример здесь (не уверен в накладных расходах).
В соответствии с документами python объект может реализовать метод __ format__ и получить спецификацию формата. В cython Im реализует мой собственный uobj-тип, который действует как общий для args и kwargs, переданных на str.format. То же самое в 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 может хранить объект пользователя (ул или ДИКТ в следующем примере), а затем могут быть доступны, как
d = uobj({'a': '<b>asdf'})
s = uobj('<span>qwer</span>')
'{0:s} {d[a]}'.format(s, d=d)
# ouputs: '<span>qwer</span><asdf'
и где отливка uobj будет происходить внутри FMT функция на * args и ** kwargs. Здесь все еще есть некоторые подробности, например, я заметил, что ints не удалось проанализировать мои unittests, и uobj нужно было бы распаковать с помощью * uobj и ** uobj для преобразования объектов по требованию, хотя мне, возможно, придется разбить это на соответствующие клоны списка и dict. Тем не менее, это, кажется, лучший путь для меня.
редактировать
кажется плохо читать на эмулировать типы контейнеров здесь http://docs.python.org/reference/datamodel.html#emulating-container-types