2011-05-07 64 views
2

我一直在使用字典來格式化字符串使用字典VS類__dict__方法格式化字符串

s = '%(name1)s %(name2)s' 
d = {} 
d['name1'] = 'asdf' 
d['name2'] = 'whatever' 
result = s % d 

我才意識到,我可以用一個類做到這一點,並使用字典方法 代替:

s = '%(name1)s %(name2)s' 
class D : pass 
d = D() 
d.name1 = 'asdf' 
d.name2 = 'whatever' 
result = s % d.__dict__ 

(顯然,我這樣做是爲了更大的字符串和許多鍵)。

我忽略了類方法有什麼缺點嗎? 或者有沒有更好的方法來做這個字符串格式,我失蹤了?

謝謝。

回答

7

可以使用新型的格式,它允許GETATTR和格式字符串的GetItem運營商:

>>> class X(object): 
...  pass 
... 
>>> x = X() 
>>> x.x = 1 
>>> d = {'a':1, 'b':2} 
>>> "{0[a]} {0[b]} {1.x}".format(d, x) 
'1 2 1' 

關於你的方法的缺點 - 對象的__dict__僅限於任何屬性和方法的具體實例有,所以任何在類級別定義的屬性/方法將失敗:

>>> class X(object): 
...  x1 = 1 
... 
>>> x = X() 
>>> x.x2 = 2 
>>> x.__dict__ 
{'x2': 2} 
>>> x.x1 
1 
>>> x.__dict__['x1'] 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
KeyError: 'x1' 

它也不會與__slots____getattribute__覆蓋工作。

+0

你的意思是說的是,'__dict__'將不包含*類級別*屬性。超類'__init__'中定義的屬性將顯示在子類實例的'__dict__'中(假定您記得讓子類「__init__」調用超類「__init__」)。 – PaulMcG 2011-05-07 16:03:42

+0

@保羅,我在我的答案中已經說明了它。 「X2」類屬性爲「x2」。但是這個類'x'的實例在'__dict__'中沒有'x2'。當你執行'x.x2'時,python會執行MRO查找,並從'X2 .__ dict__'中獲取值。 'x .__ dict__'將只保存顯式綁定到這個特定實例的值。 – 2011-05-08 00:55:19

+0

@丹尼爾,所以當你說「繼承」時,你的意思是「從它的類繼承的實例」?這是一個有趣的用法,我通常認爲繼承是從另一個階段開始的。定義爲'self.name = something'的屬性在實例中定義,並且將存儲在實例的__dict__中,而不管派生類或超類中是否發生這種情況。您關於OP的觀點是,OP的計劃是將'd .__ dict__'作爲字符串插值映射傳遞給任何class屬性;我只是覺得調用這個*繼承*問題是不正確的。 – PaulMcG 2011-05-08 01:59:12

2

您也可以考慮使用關鍵字參數,如創建字典:

d = dict(name1='foo', name2='bar') 

或使用格式的關鍵字參數:

"{name1} baz {name2}".format(name1='foo', name2='bar')