2011-12-21 3 views
1

Я знаю, что можно расширить Formatter для предоставления дополнительных типов презентаций, как описано в PEP3101, но это слишком медленно для моих нужд. Мне любопытно, какие могут быть другие варианты для ввода пользовательских типов презентаций для строк.Форматы представления строк форматирования Python/Cython

В настоящее время единственным, что приходит в голову, является проверка строки {vars} строки, обратите внимание на тип и индекс презентации, формат пользовательского представления, формат, а затем отправляйте формат результата для моих нужд.

Есть ли какие-либо другие варианты, чтобы избежать почтовой обработки, пользуясь скоростью форматирования?

ответ

1

Я разработал решение, которое, по-видимому, значительно меньше накладных расходов на 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('<', '&lt;').replace('>', '&gt;') 
    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>&lt;asdf' 

и где отливка uobj будет происходить внутри FMT функция на * args и ** kwargs. Здесь все еще есть некоторые подробности, например, я заметил, что ints не удалось проанализировать мои unittests, и uobj нужно было бы распаковать с помощью * uobj и ** uobj для преобразования объектов по требованию, хотя мне, возможно, придется разбить это на соответствующие клоны списка и dict. Тем не менее, это, кажется, лучший путь для меня.

редактировать

кажется плохо читать на эмулировать типы контейнеров здесь http://docs.python.org/reference/datamodel.html#emulating-container-types