[Python-Dev] Another case for frozendict

MRAB python at mrabarnett.plus.com
Wed Jul 16 04:27:23 CEST 2014


On 2014-07-16 00:48, Russell E. Owen wrote:
> In article
> <CAPTjJmoZHLfT3G4eqV+=ZCVbpf65fkcmah9h_8p162UHA7fQLA at mail.gmail.com>,
>   Chris Angelico <rosuav at gmail.com> wrote:
>
>> On Mon, Jul 14, 2014 at 12:04 AM, Jason R. Coombs <jaraco at jaraco.com> wrote:
>> > I can achieve what I need by constructing a set on the ‘items’ of the dict.
>> >
>> >>>> set(tuple(doc.items()) for doc in res)
>> >
>> > {(('n', 1), ('err', None), ('ok', 1.0))}
>>
>> This is flawed; the tuple-of-tuples depends on iteration order, which
>> may vary. It should be a frozenset of those tuples, not a tuple. Which
>> strengthens your case; it's that easy to get it wrong in the absence
>> of an actual frozendict.
>
> I would love to see frozendict in python.
>
> I find myself using dicts for translation tables, usually tables that
> should not be modified. Documentation usually suffices to get that idea
> across, but it's not ideal.
>
> frozendict would also be handy as a default values for function
> arguments. In that case documentation isn't enough and one has to resort
> to using a default value of None and then changing it in the function
> body.
>
> I like frozendict because I feel it is expressive and adds some safety.
>
Here's another use-case.

Using the 're' module:

 >>> import re
 >>> # Make a regex.
... p = re.compile(r'(?P<first>\w+)\s+(?P<second>\w+)')
 >>>
 >>> # What are the named groups?
... p.groupindex
{'first': 1, 'second': 2}
 >>>
 >>> # Perform a match.
... m = p.match('FIRST SECOND')
 >>> m.groupdict()
{'first': 'FIRST', 'second': 'SECOND'}
 >>>
 >>> # Try modifying the pattern object.
... p.groupindex['JUNK'] = 'foobar'
 >>>
 >>> # What are the named groups now?
... p.groupindex
{'first': 1, 'second': 2, 'JUNK': 'foobar'}
 >>>
 >>> # And the match object?
... m.groupdict()
Traceback (most recent call last):
   File "<stdin>", line 2, in <module>
IndexError: no such group

It can't find a named group called 'JUNK'.

And with a bit more tinkering it's possible to crash Python. (I'll
leave that as an exercise for the reader! :-))

The 'regex' module, on the other hand, rebuilds the dict each time:

 >>> import regex
 >>> # Make a regex.
... p = regex.compile(r'(?P<first>\w+)\s+(?P<second>\w+)')
 >>>
 >>> # What are the named groups?
... p.groupindex
{'second': 2, 'first': 1}
 >>>
 >>> # Perform a match.
... m = p.match('FIRST SECOND')
 >>> m.groupdict()
{'second': 'SECOND', 'first': 'FIRST'}
 >>>
 >>> # Try modifying the regex.
... p.groupindex['JUNK'] = 'foobar'
 >>>
 >>> # What are the named groups now?
... p.groupindex
{'second': 2, 'first': 1}
 >>>
 >>> # And the match object?
... m.groupdict()
{'second': 'SECOND', 'first': 'FIRST'}

Using a frozendict instead would be a nicer solution.



More information about the Python-Dev mailing list