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 Inheritance Super-Duper!

Andras Andras
Andras Andras
7,941 Points

OK, but...

It is not right. I used the previous code; CODE:

import random
class Character:
    def __init__(self, name, **kwargs):
        self.name = name
        for key, value in kwargs.items():
            setattr(self, key, value)
class Thief (Character):
    sneaky = True
    def pickpocket(self):
        return self.sneaky and bool(random.randint(0, 1))
    def hide(self, light_level):
        return self.sneaky and light_level < 10

and in Shell I put;

Kenneth = Thief ("Kenneth", sneaky = False)
kenneth.sneaky
False
keneth.pickpocket()
False
keneth.pickpocket()
False
keneth.pickpocket()
False

I received constantly False without the super() method. Could you please explain? So, it perfectly works without the super()

can you reformat the code by typing it in between triple backticks (`)?

Refer to the Markdown Cheatsheet if you're not sure. It helps to make the code more readable. :) thank you.

2 Answers

Kenneth Love
STAFF
Kenneth Love
Treehouse Guest Teacher

Welcome to the exciting world of class vs instance attributes!

OK, so in Character.__init__, you did setattr(self, key, value). That, combined with kenneth = Thief("Kenneth", sneaky=False) is the equivalent of doing

kenneth = Thief("Kenneth")
kenneth.sneaky = False

This sets an instance attribute (since self is the instance).

In the Thief class, we have sneaky = True. This is a class attribute since it's inside the class definition and not assigned directly to an instance.

So, then, when you do kenneth. sneaky, Python goes to check the instance to see if sneaky exists as an attribute and what its value is. It does exist, as an attribute on the instance, and it has a value of False, so that's what comes out. Let's say you had done andras = Thief("Andras") only. In this case, when you do andras.sneaky, Python goes to check the instance for a sneaky attribute and doesn't find one (you didn't provide it as a kwarg so it didn't get set on the instance). Python then goes and looks for it on the class, where it finds it and see that it has a value of True. So you're sneaky while I'm not!

I think you're only receiving false because you passed on the explicit sneaky = False argument in your instance assignment. Otherwise it should default to True.

Andras Andras
Andras Andras
7,941 Points

Of course, this is the question. Why do we use implicit if we can do the same thing with explicit.