[Python-ideas] Dict-like object with property access

Nick Coghlan ncoghlan at gmail.com
Mon Jan 30 21:56:13 CET 2012

On Tue, Jan 31, 2012 at 4:49 AM, Massimo Di Pierro
<massimo.dipierro at gmail.com> wrote:
> Trying to make sure I understand where we disagree and perhaps explain my problem better. For me this has very little to do with dictionaries.

One general challenge with "arbitrary keys as attributes" data stores
in Python is that they can get into messy namespace conflicts, because
you want to allow arbitrary keys, but you also want access to ordinary
methods. collections.namedtuple gets around this by leaving the
attribute namespace largely free for end users and prefixing method
names and class information with underscores.

Ultimately, what ends up happening as far as the standard library goes
is that "explicit is better than implicit" wins. If you don't know
what keys you're going to get, then the appropriate data structure is
a dict, not an object. If you *do* know which keys you're going to
get, then the appropriate data structure is a predefined class
(perhaps generated programmatically once the full set of permitted
attributes is determined - e.g. when creating an appropriate
namedtuple definition from a set of column headers).

*Outside* the standard library, it's "practicality beats purity" that
wins. People *like* being able to type ".attr" instead of "['attr']"
when a field name happens to be a legal identifier. The core problem
is that it's so easy to write a "good enough" version of such a class
for yourself that nobody has ever bothered to standardise on a
particular way of handling this that is suitable for stdlib inclusion
(particularly when there are so many people that object to the idea
*in principle*, regardless of the details of how it is implemented)


> STEP 4)
>  class Dummy(object):
>          def __getitem__(self,key): return getattr(self,key)
>          def __setitem__(self,key,value): return setattr(self,key,value)
>          def __getattr__(self,key):
>                  return object.__getattr__(self,key) if hasattr(self,key) else Dummy()

P.S. Tip for fast autovivification in Python:

    from collections import defaultdict

    def autodict():
        return defaultdict(autodict)

    >>> store['a']['b']['c']
    defaultdict(<function autodict at 0x7f5adfe349b0>, {})

If you want this behaviour in instances of a particular class, set the
instance __dict__ attributes to one of those in __new__ instead of
overriding __getattr__.

Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia

More information about the Python-ideas mailing list