Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

Python Object-Oriented Python Advanced Objects Subclassing Built-ins

Kohei Ashida
Kohei Ashida
4,882 Points

Why does jso.name get back 'Kenneth' while jso['language'] raises KeyError: 'language' in javascriptobject.py?

In the following code, I'm confusing in a few things.

class JavaScriptObject(dict):
    def __getattribute__(self, item):
        try:
            return self[item]
        except KeyError:
            return super().__getattribute__(item)

>>> import javascriptobject                                                                                                                                               
>>> jso = javascriptobject.JavaScriptObject({'name':'Kenneth'})                                                                                                           
>>> jso.language = 'Python'                                                                                                                                               
>>> jso.name                                                                                                                                                      
'Kenneth'                                                                                                                                                                 
>>> jso['name']                                                                                                                                                           
'Kenneth'                                                                                                                                                                 
>>> jso['language']                                                                                                                                                       
Traceback (most recent call last):                                                                                                                                        
  File "<stdin>", line 1, in <module>                                                                                                                                     
KeyError: 'language'                                                                                                                                                      

First, why does jso.name get back 'Kenneth' though the key of the value is sting type 'name' in the following lines?

>>> jso = javascriptobject.JavaScriptObject({'name':'Kenneth'})                                                                                                           
>>> jso.language = 'Python'                                                                                                                                               
>>> jso.name                                                                                                                                                      
'Kenneth'      

Second, If the case above works, why does jso['language'] raise KeyError though I've already set jso.language = 'Python' in the following lines?

>>> jso.language = 'Python'                                                                                                                                               
>>> jso.name                                                                                                                                                      
'Kenneth'                                                                                                                                                                 
>>> jso['name']                                                                                                                                                           
'Kenneth'                                                                                                                                                                 
>>> jso['language']                                                                                                                                                       
Traceback (most recent call last):                                                                                                                                        
  File "<stdin>", line 1, in <module>                                                                                                                                     
KeyError: 'language'   

Could someone give me more explanation to these things?

Thanks!

2 Answers

Steven Parker
Steven Parker
229,732 Points

Remember that "JavaScriptObject" is a dictionary, but with a customized way of accessing attributes. It looks them up in the dictionary.

So when jso is created, it already has the key 'name' defined. Because of the custom override, "jso.name" is the same thing as "jso.['name']" which returns the value from the dictionary.

But "jso.language = 'Python'" does not add a value to the dictionary., so you get an error when you try to access it.

However, if you do "jso['language'] = 'Python'" instead, it will be added to the dictionary, and you can get it back.

Timothy Mattingly
Timothy Mattingly
15,830 Points

In the video, jso.language does return 'python'

Steven Parker
Steven Parker
229,732 Points

Yes, "jso.language" returns the property directly. But "jso['language']" would not.

Kohei Ashida
Kohei Ashida
4,882 Points

Thanks for your explanation!

So when jso is created, it already has the key 'name' defined. Because of the custom override, "jso.name" is the same thing as "jso.['name']" which returns the value from the dictionary.

This makes me clear to understand what is going on here.

Thanks a lot!