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 trialFinlay Schlieper
6,935 PointsWhy do we not add the key, values of kwargs as a dictionary.
Thanks
2 Answers
Nicolas Hampton
44,638 PointsFrom 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
13,944 Pointsthanks man, you are amazing
elmira bonab
3,471 PointsI understand the unpacking of dictionary concept by unpacking a dictionary using ** when creating an instance jubjub=Monster(**{'hitpoints':4, 'color':'red'})
Chris Freeman
Treehouse Moderator 68,454 PointsChris Freeman
Treehouse Moderator 68,454 PointsDo you mean passing the arguments as a single dictionary, or evaluating **kwargs as a dictionary when adding the attributes to the instance?