2014-01-14 4 views
3

Я хочу использовать str.format() и передать ему пользовательский ленивый словарь.str.format() с ленивым dict?

str.format() должен иметь доступ только к ключу в ленивом требовании, который ему нужен.

Возможно ли это?

Какой интерфейс должен быть реализован lazy_dict?

Update

Это не то, что я хочу:

'{0[a]}'.format(d) 

мне нужно что-то вроде этого:

'{a}'.format(**d) 

нужно запустить на python2.7

+1

«' str.format() 'должен получить доступ только к ключу в ленивом запросе, который ему нужен.« Это * уже »делает это. Он делает * не * итерацию по всему словарю! – Bakuriu

+1

@Bakuriu Но в случае '** d', конвертирует доступ ко всем элементам. – glglgl

ответ

0

You может использовать метод __format__ (Pytho n 3). См. Документ here.

0

Если я правильно понял ваш вопрос, вы хотите передать пользовательский словарь, который будет вычислять значения только при необходимости. Во-первых, мы ищем для реализации __getitem__():

>>> class LazyDict(object): 
... def __init__(self, d): 
...  self.d = d 
... def __getitem__(self, k): 
...  print k    # <-- tracks the needed keys 
...  return self.d[k] 
... 
>>> d = D({'a': 19, 'b': 20}) 
>>> '{0[a]}'.format(d) 
a 
'19' 

Это показывает, что единственный ключ 'a' доступ; 'b' нет, поэтому у вас уже есть ленивый доступ.

Но и любой атрибут объекта может использоваться для str.format таким образом, и с помощью @property декоратора, вы можете получить доступ к результатам функции:

class MyObject(object): 
    def __init__(self): 
     self.a = 19 
     self.b = 20 
    def __getitem__(self, var): 
     return getattr(self, var) 
     # this command lets you able to call any attribute of your instance, 
     # or even the result of a function if it is decorated by @property: 
    @property 
    def c(self): 
     return 21 

Пример использования:

>>> m = MyObject() 
>>> '{0[c]}'.format(m) 
'21' 

Но обратите внимание, что это также работает, делая строку формирования немного специфичной, но избегая необходимости в реализации __getitem__().

>>> '{0.c}'.format(m) 
'21' 
+0

Благодарим вас за ответ. Я обновил свой вопрос. Мне очень жаль, что я больше не объяснял свои мысли. Пожалуйста, снова просмотрите вопрос. – guettli

+0

@guettli Ну, теперь я понятия не имею, как ответить на ваш вопрос; на самом деле, похоже, я даже не в состоянии заинтересовать ваш вопрос: - / –

1

Для ведения '{a}'.format(**d), особенно **d части, «ленивый» ДИКТ превращается в регулярный. Здесь происходит доступ к всем ключам, а format() ничего не может с этим поделать.

Вы можете создать некоторые прокси-объекты, которые помещаются вместо элементов, а при доступе к строкам они выполняют «настоящую» работу.

Что-то вроде

class LazyProxy(object): 
    def __init__(self, prx): 
     self.prx = prx 
    def __format__(self, fmtspec): 
     return format(self.prx(), fmtspec) 
    def __repr__(self): 
     return repr(self.prx()) 
    def __str__(self): 
     return str(self.prx()) 

Вы можете поместить эти элементы в Словаре, например

interd = { k, LazyProxy(lambda: lazydict[k]) for i in lazydict.iterkeys()} 

Я не проверял, но я думаю, что это соответствует вашим потребностям.

После последнего редактирования он теперь работает с !r и !s.

Смежные вопросы