5

I can not access the dictionary keys with dot(.) but when I define a class that inherits from dict, I can access its keys using dot(.). Can anybody explain it?

So, when I run this code:

d = {'first_key':1, 'second_key':2}
d.first_key

I get this error:

'dict' object has no attribute 'first_key'

but when I run this:

class DotDict(dict):
    pass
d = DotDict()
d.first_key = 1
d.second_key = 2
print(d.first_key)
print(d.second_key)

I get this:

1
2
awesoon
  • 32,469
  • 11
  • 74
  • 99
pythinker
  • 553
  • 5
  • 12
  • 6
    Because at that point you're just creating member variables and not necessary adding to the dictionary (in the second example) – sshashank124 May 20 '18 at 05:25
  • 1
    You have to add certain magic methods to get that functionality: https://stackoverflow.com/questions/2352181/how-to-use-a-dot-to-access-members-of-dictionary – sshashank124 May 20 '18 at 05:26
  • 1
    For example, in the second case, if you try to do `d['first_key']`, you will get a KeyError – sshashank124 May 20 '18 at 05:29
  • 4
    You should test your example without inheriting from `dict`. – Klaus D. May 20 '18 at 05:30
  • 6
    This question doesn't deserve all these downvotes. It is properly formulated. And just because something might be obvious for someone, doesn't mean it is for someone else. OP even provided their exploration about the problem – sshashank124 May 20 '18 at 05:41
  • 1
    Please reserve downvotes/upvotes for the quality/formatting of questions and not based on the simplicity/obviousness of the content/mistakes – sshashank124 May 20 '18 at 05:43
  • 1
    Take a look here: https://stackoverflow.com/questions/4984647/accessing-dict-keys-like-an-attribute – PM 2Ring May 20 '18 at 05:49
  • 1
    Also see this question, about `AttributeError` for dict: https://stackoverflow.com/questions/1529002/cant-set-attributes-of-object-class – awesoon May 20 '18 at 06:18
  • 1
    Are you coming from a JavaScript background? Python dictionaries may look like JS Objects but they aren't equivalent – juanpa.arrivillaga May 20 '18 at 06:37
  • 1
    There are many reasons to not use the "dot-as-dict-entry-getter" model in Python. Example: what if the data has a key like `'len'` or `'get'` or another method name on your class? This would break code that uses those methods. Example: how would you access keys that aren't valid Python names like `1` or `dash-name`? You'd have to mix dot and `[]` notation, ick. It's best to use the existing language construct. Don't try to recreate JavaScript syntax in Python. – Chris Johnson May 20 '18 at 13:59
  • I figured it out. Thanks for your consideration @sshashank124 – pythinker May 23 '18 at 14:09
  • Thanks @KlausD.. Your comment helped me. – pythinker May 23 '18 at 16:53
  • Thanks for your help @PM2Ring – pythinker May 23 '18 at 16:56
  • Thanks @soon. I appreciate your help. – pythinker May 23 '18 at 16:57
  • No, I’m not. Thanks for your tips @juanpa.arrivillaga – pythinker May 23 '18 at 16:59
  • Your comments helped me. Thanks @ChrisJohnson – pythinker May 23 '18 at 17:00

3 Answers3

4

By applying your example

class DotDict(dict):
    pass

d = DotDict()
d.first_key = 1
d.second_key = 2
print(d.first_key)
print(d.second_key)

you set instance parameters first_key and second_key to your DotDict class but not to the dictionary itself. You can see this, if you just put your dictionary content to the screen:

In [5]: d
Out[5]: {}

So, it is just an empty dict. You may access dictionaries the common way:

In [1]: d={}

In [2]: d['first'] = 'foo'

In [3]: d['second'] = 'bar'

In [4]: d
Out[4]: {'first': 'foo', 'second': 'bar'}
ferdy
  • 7,366
  • 3
  • 35
  • 46
2

in the first case, you are creating keys and values belonging to a dictionary object. while in the second, you are creating attributes of a class which has nothing to do with the dictionary parent class you inherited.

lelouchkako
  • 123
  • 1
  • 7
1

If you want to access the dict elements need to access through keys.

d['first_key']

Output:

1

If you want to access using (.) then use get.

Using get you can get the required value

d = {'first_key':1, 'second_key':2}
print(d.get('first_key'))

Output:

1

With respect to class you are accessing the attributes of class. So you will have to access using (.)