Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #39655

Re: Question about defaultdict

References <kga4nc$4jm$1@ger.gmane.org>
Date 2013-02-23 21:29 +1100
Subject Re: Question about defaultdict
From Chris Angelico <rosuav@gmail.com>
Newsgroups comp.lang.python
Message-ID <mailman.2334.1361615362.2939.python-list@python.org> (permalink)

Show all headers | View raw


On Sat, Feb 23, 2013 at 9:13 PM, Frank Millman <frank@chagford.com> wrote:
> I thought I could replace this with -
>
> from collections import defaultdict
> my_cache = defaultdict(fetch_object)
> my_obj = my_cache['a']
>
> It does not work, because fetch_object() is called without any arguments.

A reasonable thing to ask for, but not supported by the default
defaultdict. However, the key to defaultdict is the __missing__
method, and you can simply subclass dict and provide that method:

class cache(dict):
    def __missing__(self,key):
        val=fetch_object(key)
        self[key]=val
        return val

Alternatively, if you want to pass fetch_object as a parameter,
subclass defaultdict:

>>> class parameterizing_defaultdict(collections.defaultdict):
	def __missing__(self,key):
		value=self.default_factory(key)
		self[key]=value
		return value

>>> my_cache=parameterizing_defaultdict(fetch_object)
>>> my_cache["a"]
Expensive operation involving a
1
>>> my_cache["a"]
1
>>> my_cache["a"]
1
>>> my_cache["ab"]
Expensive operation involving ab
2
>>> my_cache["abc"]
Expensive operation involving abc
3

defaultdict does do some other work, but unless you need it, I'd be
inclined to go with just subclassing dict directly; in fact, it may
make sense to just in-line the fetch_object code right there in the
class.

There are several ways to go about it; you know your project better
than anyone else does!

ChrisA

Back to comp.lang.python | Previous | Next | Find similar | Unroll thread


Thread

Re: Question about defaultdict Chris Angelico <rosuav@gmail.com> - 2013-02-23 21:29 +1100

csiph-web