Python Object-Oriented Python Inheritance Multiple Superclasses

Philip Schultz
Philip Schultz
11,322 Points

"What are those class attributes for?"

Hello Everyone, I posted a different question regarding this code on stackoverflow and someone brought this question to my attention and I didn't know how to answer it . I was hoping someone can explain to me why Keenth decided to declare the sneaky and agile variables on the class level and in the init parameters.

Here is his question "Which raises another point: What are those class attributes for? If you wanted them to provide default values, you've already got default values on the initializer parameters for that, so they're useless.

If you wanted them to provide values during initialization, then they're potentially wrong, so they're worse than useless. If you need to have a self.sneaky before calling Character.init, the way to do that is simple: just move self.sneaky = sneaky up before the super() call.

In fact, that's one of the strengths of Python's "explicit super" model. In some languages, like C++, constructors are always called automatically, whether from inside out or outside in. Python forcing you to do it explicitly is less convenient, and harder to get wrong—but it means you can choose to do your setup either before or after the base class gets its chance (or, of course, a little of each), which is sometimes useful."

here is the code in question

class Character:
    def __init__(self, name="", **kwargs):
        if not name:
            raise ValueError("'name' is required")
        self.name = name

        for key, value in kwargs.items():
            setattr(self, key, value)


class Agile:
    agile = True

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


class Sneaky:
    sneaky = True

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


class Thief(Agile, Sneaky, Character):
    def pickpocket(self):
    return self.sneaky and bool(random.randint(0, 1))


parker = Thief(name="Parker", sneaky=False)

If you are interested here is the original post. https://stackoverflow.com/questions/52013570/how-mro-super-works-in-python

Thanks,

Jay Reyes
Jay Reyes
Python Web Development Techdegree Student 15,935 Points

yeah I'm also wondering the point of agile = True and sneaky = True when we set their default values inside of the init

1 Answer

Jeff Muday
MOD
Jeff Muday
Treehouse Moderator 23,698 Points

I agree that the design choice is confusing. The video is not prescriptive, but descriptive. The design he shows is not suggesting best practice, but that one can override default values of an object via reassignment in the init. Furthermore, the order of inheritance is significant. It gets more complex as you go on by adding the additional concept of setters and getters.

The overarching point of the video is to demonstrate inheritance and multiple inheritance. In addition, it illustrates what can be done via MRO (multiple resolution order). The ORDER of inheritance is significant as to what the child object inherits.

You're going to see MRO when you study intermediate Django ORM (object relational mapper) and Class-based views that leverage "mixins."

https://www.python.org/download/releases/2.3/mro/

lenielson sousa
lenielson sousa
2,739 Points

The design choice is really confusing, I am having such a hard time understanding this topic, but the number of questions in each topic, I would say a lot of students are having the same issue. Too bad, since it is a solid foundation that everyone needs to become a good developer.