Locked learning resources

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

Unlock This Lesson

Locked learning resources

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

Unlock This Lesson

Adding Methods to a Python Class

In this video, we start adding behaviors to our dog class.

Behaviors are called Instance Methods in Python. A method is a function that belongs to a class. Just like functions, these methods can accept parameters, and they can access the attributes of the object they belong to.

class Dog:

    species = 'mammal'

    def __init__(self, name, age):
        self.name = name
        self.age = age

    def speak(self, sound):
        print(f"{self.name} says {sound}")
philo = Dog("Philo", 5)
philo.speak("Gruff gruff!")

00:00 Welcome back to our series on object-oriented programming in Python. In the last video, we created this Dog class here and we printed some information about each of our Dog objects to the screen. If you remember from the slides, we created Door objects that could be opened, closed, and locked.

00:19 I called these behaviors just to demonstrate the concepts, but in Python, these are actually called instance methods. A method is basically just a function that belongs to a class. It’s used in the exact same way as a function, except—like the initializer—we must include a self parameter. Let’s actually create some instance methods.

00:41 First, we need a way for the Dog to report its attributes in a nice, formatted way, so we’ll create the new instance method called .description()and remember that we need to include the self parameter here. And now we’ll type return "{} is {} years old" and we’ll use the handy .format() function to fill in those blanks ({}), passing in self.name and self.age as the arguments. Notice here how we are not directly printing to the console.

01:11 Instead, we have this method returning a nice formatted string with a dog’s attributes baked into it, so we’ll need to print that out manually later on. Next, we should add a way for the dog to speak something, so let’s create a new instance method and we’ll call this one .speak().

01:29 This will take a self parameter, just like before, but I want our dog to be able to say whatever we tell him to, so let’s add another parameter called sound.

01:39 This will need to be provided when we call this method later on. Finally, we will return a formatted string where the Dog.name says the sound that we pass in, just like before. Now, let’s delete all of this old code from last time and we’ll create a new Dog object called Mikey with a name of "Mikey" and an age of 6.

02:01 Just like with attributes, we can use . to access instance methods, too. Now, you might be tempted to write mikey.description(), here—and while technically, that’s not wrong, that wouldn’t actually output anything to the console.

02:15 That’s because we have the .description() method returning a formatted string, rather than directly printing it, and so this code here will get that formatted string and then do literally nothing with it. If we want to actually see it, we need to pass the return of this method call into the print() function.

02:34 Next, let’s use our .speak() method. We’ll write print(mikey.speak()) and we’ll pass in "Gruff gruff!". And now, if we right-click and choose Run Code, we’ll see that on the right we have Mikey is 6 years old, followed by Mikey says Gruff gruff!.

02:51 As you can see, our instance methods work and they can access both attributes that belong to the current object, as well as new data we pass in the form of a method parameter.

03:03 Let’s create one more instance method that will be called every time the dog celebrates his birthday. We’ll move back into our class here and we’ll call this new method .birthday().

03:14 Now in the method body, I’ll type self.age += 1, which will increase the dog’s .age attribute by 1. In other words, every time this method is called, the dog’s internal .age attribute will increase by 1. So now, at the very bottom, I can say mikey.birthday() and then I can print out mikey.description() again.

03:38 Notice how we didn’t have to put our .birthday() method call inside of a print() function. This is because the .birthday() function doesn’t actually return any data that we can print. It just changes the internal .age attribute for our Dog.

03:52 So now, if I right-click and I choose Run Code, you’ll see that we have Mikey is 6 […] Gruff gruff!, and now, Mikey is 7 years old.

04:03 At this point, we’re almost to the end of our OOP tutorial, but I have to warn you: the last part can be a little bit difficult to grasp if you don’t already have at least a basic understanding of everything we’ve covered so far.

04:16 I would strongly suggest practicing these concepts by creating your own Python classes and then instantiating them. Remember, a class can be practically any noun, so look around you and see if you can model something in your code. And ask yourself some questions when you design your class: What attributes does the object have?

04:36 Do all objects have the same value for that attribute by default, or are they all new from the time they’re created? What behaviors does this object actually exhibit? And how might these behaviors change the attributes of the object? If you’re really up for a challenge, create a class where one of its attributes is actually another custom type you define, just as we did with the Tab class storing a Page object.

05:02 If you can do that, then you should definitely have a solid grasp on this material and you’ll be all set to move on. And on the other hand, if you’re still struggling with this—don’t feel bad at all. Like I mentioned at the very beginning, this is a difficult concept for lots of new programmers to grasp, including myself.

05:20 It requires you to think about your software in a way that’s probably completely foreign to you, and this is not something that’s easy to master.

05:28 If you’re confused about something or you just forgot it, it’s a good idea to rewatch earlier parts of the series, or even read the written tutorial that this video is largely based off of over at realpython.com. Give yourself lots of time to practice, and once you feel that you’ve got a grasp on the concepts, come back and learn about the last concept called object inheritance.

05:51 I’ll see you there.

Avatar image for chauncey

chauncey on July 9, 2020

I took your advice and looked around the room. I saw a box of popcorn, so here is what I came up with:

class Popcorn:
    status = 0

    def __init__(self, flavor):
        self.flavor = flavor

    def description(self):
        if self.status == 0:
            return f"This is a bag of un-popped {self.flavor} popcorn."
        elif self.status == 1:
            return f"This is a bag of freshly popped {self.flavor} popcorn."
            return f"You overcooked your {self.flavor} popcorn by cooking it too much."

    def pop(self):
        self.status += 1

If you’re going through this course like me, grab some popcorn and keep on going! It comes in any flavor you like (just don’t pop it too much)!

Avatar image for sangeeth2kin

sangeeth2kin on Jan. 21, 2021

Why the below does not work?

def birthday(self):
    return self.age += 1
Avatar image for Bartosz Zaczyński

Bartosz Zaczyński RP Team on Jan. 21, 2021

@sangeeth2kin The code looks fine, but it would help to clarify what you mean by saying it doesn’t work 😊

Are you getting a runtime exception? If so, would you mind sharing the error message, please? Does the program work but gives incorrect results? Or maybe nothing happens at all?

Without knowing the context and elaborating on the expected vs. actual outcome, we can only guess what went wrong. My wild guess is that the .age property might not have been initialized in the class.

Avatar image for sangeeth2kin

sangeeth2kin on Jan. 22, 2021

Hello Bartosz,

I get the below error message

File "<ipython-input-42-527d42b7a18b>", line 18
    return self.age += 1
SyntaxError: invalid syntax

This is the code:

class dog:
    species = 'mammal'

    def __init__(self,name,age):
        self.name = name
        self.age = age

    def description(self):
        return "{} is {} ".format(self.name,self.age)

    def speak(self,sound):
        return "{} says {} ".format(self.name,sound)

 #   def birthday(self):
 #        self.age = self.age+1

    def birthday(self):
        return self.age += 1

tiger = dog("tiger",3)


print(tiger.speak("woh woh"))


Avatar image for sangeeth2kin

sangeeth2kin on Jan. 22, 2021

Ok the below works:

def birthday(self):
    self.age += 1
Avatar image for Bartosz Zaczyński

Bartosz Zaczyński RP Team on Jan. 22, 2021

@sangeeth2kin Oh, actually, I haven’t noticed that your previous code wasn’t okay. You were trying to return an assignment statement instead of an expression. Pardon me 🤦

Avatar image for Andrew

Andrew on April 19, 2021

Can I declare and define a function in a class; that is a method without self-parameter?

class dog():

    def goof(goofy):
Avatar image for Martin Breuss

Martin Breuss RP Team on April 19, 2021

Hi @Andrew, yes you can do that, but you’ll have to prefix it with the @staticmethod decorator:

def goof(goofy):

You can read more about it in Python’s Instance, Class, and Static Methods Demystified.

Avatar image for gilpinbmchs

gilpinbmchs on May 26, 2021

for the class methods “description” and “speak”, is there any reason you shouldn’t just use the print() function inside of the definition instead of return?

This way you wouldn’t have to call the method inside of the print function in the main program.

Avatar image for Martin Breuss

Martin Breuss RP Team on May 26, 2021

@gilpinbmchs you’ll generally want to return values from functions instead of using print().

This gives you the advantage that you can re-use the values that your function produces in other parts of your code. If you use print(), which is also just a Python function that writes to your console and returns None, you can’t do anything besides showing a value on the console.

Avatar image for gilpinbmchs

gilpinbmchs on May 26, 2021

Makes sense. Thanks for your help!

Avatar image for Leonardo Di Domenico

Leonardo Di Domenico on July 30, 2021

@orinax I’m not sure that in your Popcorn class is a good idea using self to access the class member status. I think would be better to use Popcorn.status instead of self.status. It’s not an instance member. Is it right?

Avatar image for gb

gb on Dec. 5, 2021

@Leonardo the problem with using Popcorn.status is that it would change the status of the whole class, which would change the popped satus for all instances of the class - in other words, if you wrote Popcorn.status += 1 for the last line, calling .pop on one bag of popcorn would result in all the bags of popcorn being popped.

Become a Member to join the conversation.