Philip Schultz11,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
Jeff MudayTreehouse 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."