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 Multiple Superclasses

Maximiliane Quel
PLUS
Maximiliane Quel
Courses Plus Student 55,489 Points

Object level and instance attributes

I don't understand why we are setting both an object level attribute, e.g. sneaky and then setting the same attribute with a default value through the init method. We have done this in other parts of the course as well. Does anyone have an explanation of why we do that?

Example:

class Sneaky:
    sneaky = True

    def __init__(self, sneaky=True, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.sneaky = sneaky

    def hide(self, light_level):
        return self.sneaky and light_level < 10

3 Answers

Mathew Tran
PLUS
Mathew Tran
Courses Plus Student 10,205 Points

That's a good question. From my experience.

Usually for functions, you can define default values for certain parameters where it's most likely going to be the same value each time. When you have default values, you can omit adding the value for that parameter, if you are okay with the default

An example of it's usage

def walk(sneaky = True):
    if sneaky:
        print("Walking silently")
    else:
        print("Walking loudly")

walk() # Walking Silently
walk(True) # Walking Silently
walk(False) # Walking loudly
Maximiliane Quel
Maximiliane Quel
Courses Plus Student 55,489 Points

That would explain why someone would want to set a default value. But what I mean is why are we setting sneaky for every single instance and then set it again in the __init_ method? It seems to me that is tautologous, isn't it? Especially since we are setting a default value. Because as far as I understand it, since there is this default value every instance will have that attribute set, even if not explicitly passed in at instantiation. So why also set it at the object level? Since we do it again and again I figure there must be a reason that escapes me.

Mathew Tran
PLUS
Mathew Tran
Courses Plus Student 10,205 Points

The way this is implemented, it provides the programmer a choice for the sneaky attribute to be false, it doesn't always have to be true when Sneaky is instantiated.

Maximiliane Quel
Maximiliane Quel
Courses Plus Student 55,489 Points

I understand that. But I still don't see why we need to set sneaky at the object level. Let me put it differently. Why are we not saying:

class Sneaky:
    def __init__(self, sneaky=True, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.sneaky = sneaky

    def hide(self, light_level):
        return self.sneaky and light_level < 10 

That is my question. My question is why I would set sneaky outside of the init method. It seems like I am doing double the work ...

Mathew Tran
PLUS
Mathew Tran
Courses Plus Student 10,205 Points

Ah, totally misunderstood that. Now that you mention it, It looks unnecessary for the current implementation. Maybe if you have different overloaded constructors in your Sneaky class and you don't set sneaky to anything, it will at least be true, instead of null