2014-09-20 99 views
3

我想有一個像dictclass TestClass它有一個非默認參數。當我訪問時,我不知道所請求的元素是否已經存在。所以TestClasspython:defaultdict與非默認參數

class TestClass(object): 
    def __init__(self, name): 
     self.name = name 
     self.state = 0 
    def getName(self): 
     self.state = self.state + 1 
     return "%s -- %i" % (self.name, self.state) 

然後dict和訪問功能:

db = {} 
def getOutput(key): 
    # this is a marvel in the world of programming langauges 
    if key not in db: 
     db[key] = TestClass(key) 
    return db[key] 

和實際測試代碼:

if __name__ == "__main__": 
    print "testing: %s" % getOutput('charlie').getName() 

尼斯。但我想知道是否有更優雅的解決方案。瀏覽時,defaultdict進入我的腦海。但是,這是行不通的,因爲我不能傳遞參數給default_factory

from collections import defaultdict 
d = defaultdict(TestClass) 
print "testing %s" % d['tom'].getOutput() 

TypeError: __init__() takes exactly 2 arguments (1 given) ......我是有另一種解決方案?

此外,我想改進我的Python。所以任何其他建議也歡迎;-)

回答

4

defaultdict工廠確實沒有參數。

然而,您可以創建自己的變體,即確實是;關鍵是在定義__missing__方法:

class TestClassDict(dict): 
    def __missing__(self, key): 
     res = self[key] = TestClass(key) 
     return res 

每當dict[key]爲不存在的key訪問時,__missing__方法被調用。 defaultdict每次都使用此掛鉤返回factory(),但您可以自行提供並通過key

演示:

>>> class TestClass(object): 
...  def __init__(self, name): 
...   self.name = name 
...   self.state = 0 
...  def getName(self): 
...   self.state = self.state + 1 
...   return "%s -- %i" % (self.name, self.state) 
... 
>>> class TestClassDict(dict): 
...  def __missing__(self, key): 
...   res = self[key] = TestClass(key) 
...   return res 
... 
>>> db = TestClassDict() 
>>> db['charlie'].getName() 
'charlie -- 1' 
>>> db 
{'charlie': <__main__.TestClass object at 0x102f72250>} 
+0

很好的解決方案。謝謝! – user3474620 2014-09-20 20:09:06

+0

這真的很酷,我能找到的唯一答案很容易顯示如何做到這一點 – citizen2077 2017-06-16 10:22:15