2014-01-14 54 views
3

我想使用str.format()並傳遞一個自定義的懶字典。str.format()用懶字典?

str.format()應該只能訪問它所需的懶字典中的密鑰。

這可能嗎?

lazy_dict需要實現哪個接口?

更新

這不是我想要的:

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

我需要的是這樣的:

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

需要在Python2.7

+1

「'str.format()'應該只訪問它需要的懶代碼中的密鑰」它*已*執行此操作。它不*遍歷所有字典! – Bakuriu

+1

@Bakuriu但在'** d'的情況下,會話訪問所有項目。 – glglgl

回答

0

你跑可以使用__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爲好。