Welcome to the Treehouse Community

The Treehouse Community is a meeting place for developers, designers, and programmers of all backgrounds and skill levels to get support. Collaborate here on code errors or bugs that you need feedback on, or asking for an extra set of eyes on your latest project. Join thousands of Treehouse students and alumni in the community today. (Note: Only Treehouse students can comment or ask questions, but non-students are welcome to browse our conversations.)

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and a supportive community. Start your free trial today.

Python Object-Oriented Python Advanced Objects Subclassing Built-ins

Kohei Ashida
Kohei Ashida
4,881 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
215,396 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
14,445 Points

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

Steven Parker
Steven Parker
215,396 Points

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

Kohei Ashida
Kohei Ashida
4,881 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!