Adding Methods to a Python Class
In this lesson, 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.
sangeeth2kin on Jan. 21, 2021
Why the below does not work?
def birthday(self):
return self.age += 1
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.
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.description())
print(tiger.speak("woh woh"))
tiger.birthday()
print(tiger.description())
sangeeth2kin on Jan. 22, 2021
Ok the below works:
def birthday(self):
self.age += 1
print(self.age)
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 🤦
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):
print(goofy)
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:
@staticmethod
def goof(goofy):
print(goofy)
You can read more about it in Python’s Instance, Class, and Static Methods Demystified.
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.
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.
gilpinbmchs on May 26, 2021
Makes sense. Thanks for your help!
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?
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.
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:
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)!