Instance Methods vs Static Methods
To date we have been using instance methods, these methods are bound to an instance of a class (object) and can access the attributes attached to that instance.
In this lesson, we will take a look at another type, static methods.
Instance Methods
Instance methods are methods that are bound to a given instance of a class (object) and therefore have access to the instance data, the data attached to self
.
The first parameter, by convention, should be self
which is a reference to the instance.
For example,
class Pet:
""" A pet class """
def __init__(self, name, age):
## instance attributes
self.name = name
self.age = age
# instance method, self should be the first parameter
def talk(self):
print(f"Hi, my name is {self.name} and I am {self.age} years old.")
if __name__ == "__main__":
pet_one = Pet("Fidget", 17)
pet_one.talk()
will print out:
Hi, my name is Fidget and I am 17 years old.
We can also have other parameters in a method, but self
is still the first parameter. For example, we can add another parameter n
to talk()
, this will actually be the first parameter of the method call.
For example,
class Pet:
""" A pet class """
def __init__(self, name, age):
## instance attributes
self.name = name
self.age = age
# instance method, self should be the first parameter
def talk(self, n):
for _ in range(n):
print(f"Hi, my name is {self.name} and I am {self.age} years old.")
if __name__ == "__main__":
pet_one = Pet("Fidget", 17)
pet_one.talk(3) # call the method pet_one with n=3
will print out:
Hi, my name is Fidget and I am 17 years old.
Hi, my name is Fidget and I am 17 years old.
Hi, my name is Fidget and I am 17 years old.
We say talk()
takes 1 parameter, self
is not included.
Static Methods
A static method is a method that does not have access to the instance attributes, but it can access a class attribute (read-only). It is bound to the class. Therefore, we do not need an instance of the class to use the method
Here we have a single class attribute no_pets
that tracks the number of pets (instances) of Pet
created. We also create a static method called print_no_pets
, which uses the class attribute.
class Pet:
""" A pet class """
# define a class attribute
no_pets = 0
def __init__(self, name, age):
self.name = name
self.age = age
# increment class attribute by 1
Pet.no_pets += 1
@staticmethod
def print_no_pets():
print(f"There are {Pet.no_pets} pets.")
if __name__ == "__main__":
# call the static method on the class
Pet.print_no_pets() # prints There are 0 pets.
pet_one = Pet("Fidget", 12)
pet_two = Pet("Rex", 5)
pet_three = Pet("Indie", 7)
# call the static method on the class
Pet.print_no_pets() # prints There are 3 pets.
# call the static method via the instance
pet_one.print_no_pets() # prints There are 3 pets.
You will notice that we have used the decorator @staticmethod
. This tells the method that the first parameter should not be treated as the instance reference (normally self
).
We also did not need an instance of the class to call the method, but we could also call the method using an instance. This is the same as with class attributes, please read the part about instance and class namespaces in the Class Attribute lesson.
Here is another example of a Mathematics
class, normally we would do this as a module in Python, but in other languages such as Java and C#, classes like this with static methods are quite common. Normally referred to as a utility (helper) class.
It is also a pretty useless class as all of these are built into Python.
The point is we do not need an instance of the class to use it!
class Mathematics:
@staticmethod
def add(x,y):
return x + y
@staticmethod
def sub(x,y):
return x - y
@staticmethod
def pow(x,n):
return x**n
if __name__ == "__main__":
print(Mathematics.add(10,5)) # prints 15
print(Mathematics.sub(10,5)) # prints 5
print(Mathematics.pow(10,3)) # prints 100
=== TASK ===
Create a class called Person
. This should have a first_name
, surname
and age
attribute.
Create a static method called format_name_comma()
. The reason we want this to be static is we can imagine that it has a use even when we don't have an instance of the class.
You should be able to invoke format_name_comma()
as follows:
print(Person.format_name_comma("Joe", "Bloggs")) # prints Bloggs, Joe
You should also implement the __str__()
method which should return the formatted name using the instance attributes first_name
and surname
. Really you should reuse the static method format_name_comma()
from within __str__()
.
You should then be able to run the following code.
person_one = Person("Joe", "Bloggs", 27)
print(person_one) # prints Bloggs, Joe
Getting Started
You can copy and paste the following into a new Python file to get started.
class Person:
pass
if __name__ == "__main__":
print(Person.format_name_comma("Joe", "Bloggs")) # prints Bloggs, Joe
person_one = Person("Joe", "Bloggs", 27)
print(person_one) # prints Bloggs, Joe