Path: csiph.com!usenet.pasdenom.info!weretis.net!feeder1.news.weretis.net!feeder.erje.net!newsfeed.xs4all.nl!newsfeed5.news.xs4all.nl!xs4all!post.news.xs4all.nl!not-for-mail Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.014 X-Spam-Evidence: '*H*': 0.97; '*S*': 0.00; 'base.': 0.05; 'assuming': 0.09; 'constructor': 0.09; 'method,': 0.09; 'override': 0.09; 'stealing': 0.09; 'class:': 0.16; 'declared': 0.16; 'enigma': 0.16; 'help?': 0.16; 'kern': 0.16; 'received:80.91': 0.16; 'received:80.91.229': 0.16; 'received:gmane.org': 0.16; 'received:list': 0.16; 'subclass': 0.16; 'subclasses': 0.16; 'underlying': 0.16; 'argument': 0.18; 'robert': 0.18; 'def': 0.20; 'previously': 0.20; 'wrote:': 0.21; 'function': 0.22; 'instead.': 0.22; 'subject:Question': 0.22; 'header:In-Reply-To:1': 0.22; 'header:User-Agent:1': 0.23; '>>>': 0.24; 'this?': 0.24; 'quite': 0.26; 'regular': 0.26; 'seems': 0.28; 'this.': 0.28; 'pm,': 0.28; '(by': 0.29; 'default,': 0.29; 'code': 0.29; 'class': 0.29; "i'd": 0.29; 'skip:s 20': 0.34; 'url:python': 0.34; 'there': 0.35; '(and': 0.35; 'beginning': 0.35; 'skip:_ 10': 0.35; "i'm": 0.36; 'sure': 0.36; 'header:X-Complaints-To:1': 0.36; 'web,': 0.36; 'url:library': 0.36; 'but': 0.36; 'url:org': 0.36; 'does': 0.36; 'thank': 0.37; 'list': 0.37; 'something': 0.38; 'called': 0.38; 'received:org': 0.38; 'list,': 0.38; 'clear': 0.39; "can't": 0.39; 'to:addr:python-list': 0.39; 'allow': 0.39; 'think': 0.40; 'how': 0.40; 'to:addr:python.org': 0.40; 'act': 0.60; 'your': 0.60; "here's": 0.61; 'relatively': 0.63; 'our': 0.64; 'easy': 0.65; 'world': 0.65; 'sounds': 0.66; 'lower': 0.67; 'believe': 0.67; 'idea.': 0.72; 'realized': 0.72; 'telling': 0.77; 'factory': 0.84; 'terrible': 0.84; 'eco': 0.91 X-Injected-Via-Gmane: http://gmane.org/ To: python-list@python.org From: Robert Kern Subject: Re: Question about collections.defaultdict Date: Mon, 26 Mar 2012 16:52:47 +0100 References: <4F707028.4000407@syslang.net> <4F708C4C.5050700@syslang.net> Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Gmane-NNTP-Posting-Host: 94.197.127.115.threembb.co.uk User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.7; rv:11.0) Gecko/20120313 Thunderbird/11.0 In-Reply-To: <4F708C4C.5050700@syslang.net> X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Newsgroups: comp.lang.python Message-ID: Lines: 80 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1332777189 news.xs4all.nl 6887 [2001:888:2000:d::a6]:48370 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:22198 On 3/26/12 4:33 PM, Steven W. Orr wrote: > On 3/26/2012 9:44 AM, Robert Kern wrote: >> On 3/26/12 2:33 PM, Steven W. Orr wrote: >>> I created a new class called CaseInsensitiveDict (by stealing from code I found >>> on the web, thank you very much). The new class inherits from dict. It makes it >>> so that if the key has a 'lower' method, it will always access the key using >>> lower >>> >>> I'd like to change the place where I previously declared a dict >>> >>> self.lookup = defaultdict(list) >>> >>> so that the new code will allow this new dict to be used instead. But then I >>> realized I may have painted myself into a small corner: >>> >>> Is there a way to use defaultdict so that I can override what *kind* of dict it >>> will use? >> >> No. >> >>> I would like the value to still be a list be default, but it seems like I can't >>> tell defaultdict to use *my* new dict. >>> >>> Do I give up on defaultdict? >> >> Assuming that your CaseInsensitiveDict subclasses from dict or UserDict, it's >> relatively easy to make a subclass of your CaseInsensitiveDict act like a >> defaultdict. Just implement the __missing__(key) method appropriately (and >> modify the constructor to take the callable, of course). >> >> http://docs.python.org/library/stdtypes.html#dict >> http://docs.python.org/library/collections.html#collections.defaultdict.__missing__ >> >> >> > > I'm not quite getting what you're telling me, but I'm sure you have the right > idea. Here's the beginning of my class: > > class CaseInsensitiveDict(dict): > def __init__(self, init=None): > if isinstance(init, (dict, list, tuple)): > for kk, vv in init.items(): > self[self.key_has_lower(kk)] = vv > > > It sounds like you want me to subclass defaultdict to create something like this? > > class CaseInsensitiveDictDef(defaultdict): > def __init__(self, init=None): > super(CaseInsensitiveDictDef, self).__init__(list) > self.__missing__ = list > > I think I'm way off base. I'm not clear on what the calling sequence is for > defaultdict or how to get it to use my CaseInsensitiveDict instead of regular dict. > > Can you help? You need to make a subclass of CaseInsensitiveDict, implement the __missing__(key) method, and override the __init__() method to take the factory function as an argument instead of data. defaultdict is just a subclass of dict that does this. class CaseInsensitiveDictDef(CaseInsensitiveDict): def __init__(self, default_factory): super(CaseInsensitiveDictDef, self).__init__() self.default_factory = default_factory def __missing__(self, key): return self.default_factory() -- Robert Kern "I have come to believe that the whole world is an enigma, a harmless enigma that is made terrible by our own mad attempt to interpret it as though it had an underlying truth." -- Umberto Eco