Join us and get access to hundreds of tutorials and a community of expert Pythonistas.

Unlock This Lesson

This lesson is for members only. Join us and get access to hundreds of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Hint: You can adjust the default video playback speed in your account settings.
Hint: You can set the default subtitles language in your account settings.
Sorry! Looks like there’s an issue with video playback 🙁 This might be due to a temporary outage or because of a configuration issue with your browser. Please see our video player troubleshooting guide to resolve the issue.

How @staticmethod and @classmethod Work With Subclasses

Give Feedback

In this video, you’ll see an example of both static methods and class methods used in a Python class. You’ll also see how these methods work when dealing with sub classes.

00:00 Next, let’s look to see how static methods and class methods work when dealing with subclasses. So, here we have a generic class called Animal, which takes a color and has a few methods defined. One class method, which takes a cls (class) argument as the first argument, and randomly picks a color for the child and returns a new instance of that particular class.

00:24 You also have a static method here that simply allows the animals to speak. The default speak is a 'Roar!'

00:31 Then we have a couple of subclasses of that particular type. One that overrides the .speak() method, so when an animal speaks—when a dog speaks, in this case—'Bark!' is printed rather than 'Roar!' And we also have a way of instantiating and calling the class for a dog.

00:52 So, we have this particular thing commented out. I have that line commented out just to show you that when we try to run this without telling it to run on the superclass, it causes a bit of a problem.

01:03 So, let’s just run through this and see. This will run fine, no big deal. We have an example here that says we created a Dog, which takes the color 'Brown'. We print that .color. So as you can see here, we print the .color of the dog, which is 'Brown'.

01:19 Then we go on to try to make a new dog, based on the instance, the d we just created above. Once we hit that, we go—boom. 'NoneType' object has no attribute 'color'.

01:30 When we try to access the .color attribute on the puppy, we get no attribute. It just doesn’t exist. You don’t have it, you don’t exist. Which is interesting, because when this returns, it returns a NoneType.

01:43 Since there is no return statement here, pup gets assigned None. And then it asked to see what the .color is—None.

01:49 There is no such thing as .color on this attribute. So in order to make this work, we simply need to initialize a way to call its superclass.

01:58 So all this says, it goes, “This, the class I’m in—make a baby.” So we can call up to the class method. Now, this is an explicit way of doing the same thing here, so if we were to just leave this all uncommented—so let’s just delete it here.

02:16 Just one second, let’s get that into the buffer here so we can easily get that back afterwards. Let’s run that and then see what happens. So, as you can see, this works completely fine. We call d.color, d.make_baby(), and then we have pup here and then we check to see the .color.

02:33 This worked fine by simply calling this thing here. So let’s just, as an example, print the class that comes in here.

02:45 So, when we go and call .make_baby(), we’ll pick a color, print the class type, and then return a new instance of that particular class type.

02:55 So as you can see—and this is the power of class methods—the class Dog got passed in, regardless of whether or not the class method was defining the subclass.

03:05 The class that you’re passing in is the class, or instance, which you call the class method from, rather.

03:13 So this time, we returned a Dog which is Golden, which is quite awesome. Now let’s put back what we had here before and see if we can grok what that does. So, when you run it this time, it won’t print the class. No, sorry. It will print the class, but it will also print 'making dog baby' just before.

03:37 Hm, we’ve got to reset that and then run this again. And as you can see this time, it ran

03:45 making dog baby and then it went through and ran through all of the static method stuff required up in here. Now, this is an idiom that you may see in .__init__() methods, where you want to do some special behavior and then call your superclass to finish doing whatever you’re doing. The same can be done with class methods, so let’s say we wanted to let somebody know that something happened.

04:06 We’d do that information here. So, # do something dog specific. Then we would then call the superclass to finish up the remainder of the work, which involves making a baby. So, you can either choose to do this, or you can simply delegate this to your superclass like we did here, or you can just leave this removed, like we had in the previous example, and simply rely on the superclass’s class method to invoke your exact behavior.

04:36 But the key thing to remember here is this, that this class method is based on either the instance or the class in which you run the method on. So in this example, d. Or in the previous example of Integer, the Integer class.

04:54 Next, let’s take a look at the static methods. Now, the static method for the Animalit only simply returns and prints 'Roar!' Now, for the Dog method, dogs clearly don’t roar, we want them to bark, so we’d have to override this behavior.

05:11 So let’s take a look. Let’s remove this real fast and see what this ends up giving us. It’ll be kind of the same.

05:19 And this causes all instances of the pup, or the dog, or the .speak() method called on the class to return 'Roar!' Now let’s simply put that method back in here,

05:38 enter it, and that will cause… Now, so when the pup runs .speak()

05:50 Sorry, I’ve got to reevaluate that and I’ve got to reevaluate this. Now, in all cases here that this pup running .speak() will print a 'Bark!', the instance of Dog running .speak() will print 'Bark!', and the class running .speak() will print 'Bark!' This just goes to show that you can override these methods in your subclasses and they will do what the specific thing will do. So, for example, if we were to go here Animal.speak(), as you might tell, this will print 'Roar!' Now let’s take a look at the class example of Cat. With Cat we did nothing, all we did was subclass the Animal class in Cat.

06:27 So when you do anything running on Cat, it will simply produce—again, here for the class method, it took the class which the method was called on, which is c, which is of type Cat. So, as you can see here, it returns how to make a cat, prints 'Black' and returns 'Roar!', as we showed here, when we weren’t overriding it.

Become a Member to join the conversation.