2014-09-20 5 views
3

dictclass TestClass이고 기본값이 아닌 인수가 있어야합니다. 액세스 할 때 요청한 요소가 이미 도착했는지 여부는 알 수 없습니다. 그래서 TestClass :비 기본 인수가있는 파이썬 : 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 내 마음에 온다.

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

TypeError: __init__() takes exactly 2 arguments (1 given)을 제공합니다 나는 ... 또 다른 해결책이있다 : 나는 default_factory에 인수를 전달할 수 없기 때문에하지만이 작동하지 않습니다?

게다가 파이썬을 개선하고 싶습니다. 그럼 다른 제안도 환영합니다 ;-)

답변

4

defaultdict 팩토리는 실제로 인수를 취하지 않습니다.

인 변형을 직접 만들 수 있습니다. 트릭은 __missing__ 방법을 정의 할 수 있습니다 : dict[key]이 존재하지 않는 key에 대한 액세스 할 때마다

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

에서, __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

+0

이것은 정말 멋지며이 방법을 쉽게 보여주는 유일한 해결책입니다. – citizen2077

관련 문제