Python Object-Oriented Python Inheritance Multiple Superclasses

Anthony Grodowski
Anthony Grodowski
4,902 Points

Problem with name

I can't quite get why we need to set name keyword argument in order to run the code. Why do we put name="" in the init? TIA

1 Answer

Chris Freeman
MOD
Chris Freeman
Treehouse Moderator 59,730 Points

Good question. Keep in mind that a supplied positional argument would be applied to the first available parameter, be it positional or keyword parameter!

With the inclusion of Agile and Sneaky, the first positional argument "Kenneth" would be applied to the agile parameter:

# Note: `name=foo` added to pass `if not name:` test
>>> thieves.Thief("Kenneth", sneaky=True, name="foo").__dict__
{'name': 'foo', 'sneaky': True, 'agile': 'Kenneth'}

The attribute agile gets assigned "Kenneth"!

Why do we put name="" in the __init__? By supplying a default value for the parameter name it covers the case where the name might have been swallowed up by a previous positional assignment. If all the parameters are provided, keyword use isn't necessary. But if one parameter isn't filled, then name would become the default empty string and the check in Character would raise the error.

>>> thieves.Thief(True, True, "Kenneth").__dict__
{'name': 'Kenneth', 'sneaky': True, 'agile': True}
>>> thieves.Thief(True, "Kenneth").__dict__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/home/chris/devel/Treehouse/Thief/attributes.py", line 19, in __init__
    super().__init__(*args, **kwargs)
  File "/home/chris/devel/Treehouse/Thief/attributes.py", line 8, in __init__
    super().__init__(*args, **kwargs)
  File "/home/chris/devel/Treehouse/Thief/characters.py", line 4, in __init__
    raise ValueError("'name' is required")
ValueError: 'name' is required

Post back if you need more help. Good luck!!

Anthony Grodowski
Anthony Grodowski
4,902 Points

Thnak you! That cleared almost everything!

"With the inclusion of Agile and Sneaky, the first positional argument "Kenneth" would be applied to the agile parameter" - but if in Agile there would be, for example, agile = "Able To Dodge", then "Kenneth" parameter couldn't overwrite it, right? True, False and None could be eaisly overwritten by "Kenneth", but explicit keyword argument can't.

Chris Freeman
Chris Freeman
Treehouse Moderator 59,730 Points

Again, good question!

Important point: a function only has parameters, some may have default values define, others may not.

Having a default value for a parameter does not protect it being assigned to a positional argument.

In my answer above, agile is assigned “Kenneth” even though it has a default value True

Keywords only come into play if the argument in the statement calling the function has a keyword with the argument. In this case the argument will only be applied to the parameter of the same name.

If “Kenneth” had been used as an argument along with agile=True then an error would be raised saying Error: agile already assign an argument`

# Note: `name=foo` added to pass `if not name:` test
>>> thieves.Thief("Kenneth", agile=True, name="foo").__dict__
TypeError: Thief() got multiple values for argument agile