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 (retired) Objects __init__

Why do we not add the key, values of kwargs as a dictionary.

Thanks

Chris Freeman
Chris Freeman
Treehouse Moderator 68,454 Points

Do you mean passing the arguments as a single dictionary, or evaluating **kwargs as a dictionary when adding the attributes to the instance?

2 Answers

From what I can make from the question, I think Finlay is referring to this syntax:

slimey = Monster(color='yellow', sound='glug')

as opposed to defining a dictionary when passing in the arguments, like:

slimey = Monster('color': 'yellow', 'sound': 'glug')

#or

slimey = Monster({'color': 'yellow', 'sound': 'glug'})

#or

slimey = Monster({'color': 'yellow'}, {'sound': 'glug'})

If that's your question Finlay, I thought it was a good one, so I took it to the python interpreter (just type python on the command line.) A lot of the time I learn more just trying stuff in the interpreter and seeing what works, what doesn't, and what errors I get. So first I tried:

>>> slimey = Monster('color': 'blue')

#but that gave this error

SyntaxError: invalid syntax

and pointed to the colon as the source of the syntax error. I can see that, if we're going to pass a key, value pair, it needs to be inside a dictionary. So next tried:

>>> slimey = Monster({'color': 'blue'})

#Thinking that if I passed the key, value pair 
#inside a dictionary, it might work. 
#But then I received this error...

NameError: name 'color' is not defined

so the interpreter really wasn't recognizing that I was assigning the color value 'blue' to my key 'color'. When I looked at the question originally, I very quickly thought

well, we're passing in a tuple, a series of variables that we're giving values to inline

and I thought to break it down like this:

color = 'blue'
weapon = 'sword'

# see how the variables have values here, and the
# argument is just a tuple
slimey = Monster(color, weapon) 

But that's wrong, and will throw an error

TypeError:  __init__() takes 1 positional argument but three were given

I tried name-spacing different references the class had as well, such as:

>>> slimey = Monster(slimey.color = 'blue')
>>> slimey = Monster(self.color = 'blue')
>>> slimey = Monster(kwargs.color = 'blue')

and all of those combinations returned the same error:

SyntaxError: keyword can't be an expression

but, when I used the syntax we're supposed to on a property the class doesn't even have:

>>> slimey = Monster(army = 'ogre')

everything worked out, except when I tried to get slimey.army back,

AttributeError: 'Monster' object has no attribute 'army'

So here's what I've seemed to have worked out. "key = 'value'" syntax is how we work with dictionary arguments on a function or class. We get syntax errors when we use the colon, and NameErrors when we use the brackets. We can pass any key value pair in, but if we don't handle its storage in the init function (or constructor to my js/java peeps out there, what WHAT!!) then the key/value disappears anyways, so don't bother.

I don't know if this answered the theory of your question Findlay, but it was a fun exercise in how we can get a few more answers by putzing around the interpreter, so I hope it was at least worth that. I feel more solid at least. If you get a good theory answer, let me know, and Happy Coding!

Nicolas

Faisal Julaidan
Faisal Julaidan
13,944 Points

thanks man, you are amazing

elmira bonab
elmira bonab
3,471 Points

I understand the unpacking of dictionary concept by unpacking a dictionary using ** when creating an instance jubjub=Monster(**{'hitpoints':4, 'color':'red'})