1

Often, it would be convenient to access dict entries with my_dict.my_key instead of my_dict['my_key'].

So I came up with the following solution:

class ddict(dict):
    def __init__(self, **kwargs):
        dict.__init__(self, **kwargs)
        for (k, v) in kwargs.items():
            self.__dict__[k] = v

You can use it as:

    d = ddict(a = 1, b = 2)
    print(d.a)
    print(d.b)

Is that approach safe or will it bite me at some point? Is there maybe even a built-in approach?

(Why do I want that? Easier typing and looks better than a dict or an explicitly defined class, but that should not be the topic here, since it's a matter of taste and situation. And it's iterable.)

Michael
  • 7,407
  • 8
  • 41
  • 84

2 Answers2

3

A better and safer way would be to use _getattr_ (which is what Python calls when you use the . notation, but do note that this approach only allows for string keys (not integers, floats or arbitrary objects):

class ddict(dict):
    def __getattr__(self, item):
        return self[item]

d = ddict()
d['a'] = 1
print(d.a)
>> 1

You may also override __setattr__ so you can assign with the . notation as well.

class ddict(dict):
    def __getattr__(self, item):
        return self[item]

    def __setattr__(self, key, value):
        self[key] = value

d = ddict()
d.a = 1
print(d.a)
>> 1
DeepSpace
  • 78,697
  • 11
  • 109
  • 154
0

You can override __getattr__

class ddict(dict):
    def __getattr__(self, item):
        return self[item]

a=ddict({'a':'12'})
a.a

Will output '12'

To mention it's better to use UserDict from collections module

So you can override make your class more clear:

from collections import UserDict

class ddict(UserDict):
    def __getattr__(self, item):
        return self.data[item]

But this will resting using data as variable name in your ddict object, since it will be returning the whole dict object.

And as @DeepSpace noted, you probably would want to override __setattr__ to be able to set value though name.

vishes_shell
  • 22,409
  • 6
  • 71
  • 81
  • Inheriting from `UserDict` will somehow run into an infinite recursion, while inheriting from `dict` works. – Michael Nov 29 '16 at 10:18