Instructor: Hi guys and welcome back.
In this video, we're going to talk about static methods
and class methods.
These can be a little bit confusing so let's get started.
Here, we've got a class that I have called ClassTest.
This is just to show you how these things work.
And then we have defined a method.
We know it's a method because it is a function,
which starts with a def keyword,
and it has self as a first parameter.
All functions inside the class that use the object
as the first parameter,
are called instance methods.
And this instance_method,
prints that you've called the instance_method.
How would you call this method if you wanted to call it?
You have two options.
Okay, the first option is to do something like,
test = ClassTest, and create a new object of type ClassTest.
Notice that we don't have an init method in this class,
but that's okay.
If you don't have an init method,
that just means that you
don't have any initialization to do,
but the self is still created
and you still get a new object.
And make it equal to your variable.
Here, we're creating a new object
and you can do test.instance_method, or as we know it,
you can ClassTest.instance_method
with test as the argument.
Both of these things are exactly the same.
If you run this code, you'll get that you've called
the instance_method of this object.
Notice that we are printing the object self here,
and as we saw earlier on,
you get back this ugly print out.
If you wanted it to be a little bit nicer,
you would have to implement your str or repr methods,
one of the two.
But for now, we have called the instance_method two times.
It is called an instance_method because you call it
on a class instance.
The name instance, it means the same thing, an object.
What we're doing here is we're creating an object
of type ClassTest.
You can also say that you're creating
an instance of ClassTest.
They mean the same thing.
That is why these are called instance methods.
Instance methods need the object in order to call them.
The next type is called a class method.
Here, you can define another method.
But now instead of the instance, or the object, self,
it actually takes a different parameter
that we usually in Python, call cls,
but you can call this parameter whatever you want,
the value will still be the same no matter
what you call this parameter.
What this parameter will be in a class method,
that is when you put this at @classmethod on top
of the method definition, is this will be the class itself.
Let me show you how this works.
Called class_method of {cls}.
I'll just print the parameter there,
and then, because it is a class method,
it's not an instance method,
you no longer need an instance.
That means that you can just do,
ClassTest.class_method, and that's it,
you don't have to pass in anything in there
because we no longer need the object.
Python is smart enough that when you do
ClassTest.class_method and you don't pass anything in there,
Python will actually pass ClassTest in there.
So, actually cls is ClassTest,
because that is what you called the method on.
That is how this works.
When you do ClassTest.class_method,
given that you have put this @classmethod on top.
We're going to learn what this is later on.
Don't worry about it too much.
Then Python will pass in the class as the argument
to this parameter.
If we save and play,
you'll see that now you get that you've called
the class_method of this class called ClassTest.
Don't worry too much about the __main__,
we will learn about that later on if it becomes relevant.
It's largely irrelevant to most Python programmes.
This just means that you've called the class_method
of this class.
We're going to find used cases for class_methods
in just a little bit later on in this video.
Finally, the last option is the @staticmethod.
And this defines a static method that I'm going to call
static_method.
Again, you can call it whatever you want
and now I'm not going to put anything inside the brackets.
Here, we're going to do "Called static_method."
In a static method, that is a method
that doesn't have a parameter cls or self,
and that has @staticmethod on top.
These methods don't get anything when you call them.
The class method gets the class normally
and you can print it out or use it.
The instance_methods gets the instance or the object
and you can print it out or use it in them.
But static methods don't get either of those things.
And you can call them in the same way
just by doing static_method inside ClassTest
or ClassTest.static_method but Python will not put
the ClassTest in the brackets.
It will just call that method.
This really isn't a method.
It's just a function that you've placed inside a class.
We should still call it a method but it doesn't have
any information about the class or the object
so it's really just its own separate function
that lives inside the class.
If you want a function inside the class
that doesn't use the class for anything,
or the instance, you can decorate it with @staticmethod.
If you want a method that uses the class for something,
then you can decorate it @classmethod.
And if you want to use the object,
or if you wanna create any other type of instance_method,
then just don't put anything on top.
No @classmethod or @staticmethod
and make sure to include your parameter there.
Again, if you call this like that and you press play,
you just get Called static_method.
So, what are these used for?
Instance methods are used for most things.
When you wanna produce an action that uses the data
inside the object that you created earlier on for example,
that is when instance methods would get used.
Also, if you wanna call a method to modify
some sort of data inside self or the object,
then you would also use an instance method.
Class methods are used often as factories
and I'm going to show you what that is in a second.
And finally, static_methods are used to just place a method
inside a class.
Because you feel like it belongs there for some reason.
For you as a developer, you wanna put that method in there
because it makes sense logically for code organisation
or something like that, then you can use that.
I'll say though that most of the time,
you'll be using class methods and instance methods.
You won't be using static methods all that much.
Let's start with our factory example
that is going to show you how you might use a class method.
This example is gonna be a little bit tricky
so please bear with me for a second
while I explain first what I've done here.
In a class, as well as methods,
you can also put variables
and these become class properties.
If you wanted to print out this tuple here,
all you have to do is access the TYPES tuple
inside the Book class.
You would do Book.TYPES,
and that is how you access this tuple there.
You can print it out
and you can see that you get hardcover and paperback.
We have some data stored inside the class,
which is this tuple here,
and a reason why you might put some data inside a class,
as opposed to putting it outside the class,
is because you feel like it belongs there
or only the Book class is going to use it,
or maybe there is some sort of reason,
logical reason to put that data in there.
Here I'm creating a class that talks about Books.
So, it makes sense to have book types inside there.
Then we're going to create an init method for this class.
Remember, because this is an instance method
it creates an instance and gives it back to you,
you need the self parameter there.
You can call self whatever you want, once again,
but the convention in Python is to call it self.
And then we're going to be creating objects
of type Book that have three things.
A name, a book type, and a weight.
So, we will do self.name = name,
Self.book_type = book_type,
and self.weight = weight.
This is a very common thing in Python
to create an object with three different values
that you then store each one inside a property
of the object itself.
Just to recap, if you were to create a variable
such as Book, and make it an object,
then you will need to pass in some information,
let's say, "Harry Potter", "hardcover", and 1500,
then you can print book.name
and what that's going to do is it's going
to pass in "Harry Potter" as the value for this parameter.
Then that is going to be assigned to the name property
of the self object, which is essentially
an empty container at this stage,
and then we're going to print it out down here.
So if we press play,
you'll see that "Harry Potter" comes out.
That's how the data is flowing through
this system at this stage.
Then I'm also going to create a repr method
so that it's a little bit easier
to work with these books.
And we are going to return a Book with this name.
It is this Book type
and it's weighing {self.weight}g>.
This is a representation of the book that would allow us,
with all the data included inside,
to recreate a book object if we wanted to.
Remember, that is the purpose of the repr method.
If you wanted to just print the book out nicely
for users to read,
then you could use the str method instead.
Now instead of putting in book.name,
we're just going to print book and I will press play
and show you what the output is.
Here's the book, "Harry Potter."
It's a hardcover, weighing 1500 grammes.
Now we come into the factories.
Here's where we're gonna use class_methods.
I wanna avoid, when I'm creating a new book object,
when I'm calling the init method,
I want to avoid passing in this "hardcover" string
because I only want to be able to create books
that are either hardcover or paperback,
I wanna make sure that when I create a book,
I use one of these two types.
Right now, I can pass in comic book if I wanted to here
and that would be totally fine because again,
the data, this string here, becomes the value of book_type.
Book_type gets assigned to self.book_type,
and that gets used down here.
There is no check for this,
nothing is using this at the moment.
What I'm going to do is I'm going to create a method
that will take in the name and the weight
and will create a new book object of type hardcover.
I'm going to call this @classmethod hardcover,
and again, because it is a class method,
it takes in the class as the first parameter,
usually called that cls in Python.
And that is going to take in the name
and the page weight,
and what it's going to do is it is going to return a book
with the name as the first argument,
which then goes into the init method.
Book.TYPES[0] as the second argument.
Remember, Book.TYPES gives us this tuple.
Book.TYPES[0] gives us the hardcover.
And finally, the page_weight + 100
for the weight of the book.
I'm adding 100 because it's a hardcover
so it's probably going to be a little heavier
than a paperback.
Hopefully this makes sense.
It is a little bit confusing because you are using
the class inside a method defined inside the class.
Which I know is a little bit weird,
but that is how you can create a new object
inside of a class.
This is something you can totally do.
And because it is a class method,
you no longer need to create your own object first.
All you have to do now is say,
Book.hardcover and pass in here "Harry Potter"
and the page weight which was 1500.
Notice that this hardcover method takes in the name
and the page weight but it does not take in a type.
The type is added inside the method,
you don't have to pass it in as an argument.
If I save and run that,
you can see that now you get a book "Harry Potter,"
which is a hardcover, and weighs 1600 grammes.
Let's do the same thing for the paperback.
Only now instead of Book.TYPES[0],
I'm going to do Book.TYPES[1]
and I'm going to remove this + 100.
So now, if we wanted to create a softcover book,
or a paperback, you can say something like,
light = Book.paperback("Python 101"),
and you can say for example, 600.
If you then print the light book as well,
you'll see that you get two books printed out now.
Book "Harry Potter," which is hardcover, weighing 1600 grammes
and Book "Python 101," which is a paperback,
weighing 600 grammes.
This is a very, very common way of using class methods
because you have access to the class itself
inside the method, that means that it is a perfect place
to be creating new objects by using that class.
With that said though, notice that I'm using Book here
and I'm not using cls anywhere.
Book is the class as we saw earlier on.
And cls is also the class.
They are interchangeable.
Instead of Book, you can put cls in there.
And instead of Book down here, you can put cls in there.
You should do that.
Use cls instead of Book and that will come in handy
when you look at inheritance,
which we will look at later on.
Just because using cls gives you a little bit more
flexibility down the line.
Do use cls there since you've got access to it
and if you were creating a static method
instead of a class method,
you would have to use book class
because you wouldn't have cls.
If you want to use cls use a class method,
use the paramter, and you can create new objects
and return them or use them however you like.
Hopefully this makes sense.
I know that it's a little bit confusing
looking at class methods and static methods
and it's been a bit of a long video
but hopefully it was helpful.
Hope you enjoyed it and I'll see you in the next one.