The very basic Python example class is one with a name and a property.
For instance:
class Weight: kilos = 100
With this class, you can create weight objects and change their weights:
w1 = Weight() w1.kilos = 200 print(w1.kilos)
Output:
200
Let’s see some other useful class examples in Python.
Python Class with Methods Example
A super useful feature of classes is that you can add methods into the class. You can then call these methods on the objects of the class.
For example, let’s create a Weight
class. Let’s enable converting kilos to pounds with a method:
class Weight: kilos = 100 def as_pounds(self): return self.kilos * 2.208
Now it is possible to call the as_pounds()
method on any Weight
instance:
weight1 = Weight() weight1.kilos = 300 print(weight1.as_pounds())
Output:
662.4000000000001
Class with Special Methods Example
Python classes can have special methods or double-underscore methods.
Initialization Example
The most popular double-underscore method in Python is the __init__()
method. This method is responsible for initializing the new object with an initial state.
For example, a person can be given a name and age upon creation.
For example, let’s create a Person class and an initializer to it that accepts name, weight, height, and age:
class Person: def __init__(self, name, weight, height, age): self.name = name self.weight = weight self.height = height self.age = age
Now it is possible to create new Person objects by for example:
soccer_player = Person("Jack", 80, 182, 30) tennis_player = Person("Rose", 60, 163, 23)
The above code created two Person objects, a soccer player and a tennis player.
String Representation Example
We are going to continue working with the Person
class.
Let’s next create a textual representation for the class Person
. This way you can obtain useful information about the object.
Why?
Because now if you try to print a person, you get nonsense back:
print(soccer_player) print(tennis_player)
Output:
<__main__.Person object at 0x1072d0fd0> <__main__.Person object at 0x1072d0f10>
To get a user-friendly output when calling print()
on an object, override the __str__
method in the class.
class Person: def __init__(self, name, weight, height, age): self.name = name self.weight = weight self.height = height self.age = age def __str__(self): return f"This person is {self.name}. They weigh {self.weight} kilos and are {self.height} centimeters tall. They are {self.age} years old."
Let’s create two persons:
soccer_player = Person("Jack", 80, 182, 30) tennis_player = Person("Rose", 60, 163, 23)
Now you can get useful information about these persons because you just override the special methods __str__
and __repr__
:
print(soccer_player) print(tennis_player)
Output:
This person is Jack. They weigh 80 kilos and are 182 centimeters tall. They are 30 years old. This person is Rose. They weigh 60 kilos and are 163 centimeters tall. They are 23 years old.
This is cool for the end-user for example as they now can see who the Person
object is.
But what about us developers? We would like to see how this user object was created.
To create a developer-friendly representation of a Person
object, override the __repr__
method in the class.
Here is how the Person
class looks like after that:
class Person: def __init__(self, name, weight, height, age): self.name = name self.weight = weight self.height = height self.age = age def __str__(self): return f"This person is {self.name}. They weigh {self.weight} kilos and are {self.height} centimeters tall. They are {self.age} years old." def __repr__(self): return f"Person(name={self.name}, weight={self.weight}, height={self.height}, age={self.age})"
Now you can test it:
soccer_player = Person("Jack", 80, 182, 30) # User-friendly info print(soccer_player) # Developer-friendly info print(repr(soccer_player))
Output:
This person is Jack. They weigh 80 kilos and are 182 centimeters tall. They are 30 years old. Person(name=Jack, weight=80, height=182, age=30)
Comparisons Example
Let’s continue with the Person
class:
soccer_player = Person("Jack", 80, 182, 30) tennis_player = Person("Rose", 60, 163, 23)
Let’s compare these objects:
print(soccer_player == tennis_player)
Output:
False
This is not a surprising result. As the
is a different object than the soccer_player
tennis_player
, they are not the same object.
But if we do a greater than comparison:
print(soccer_player > tennis_player)
We get an error:
TypeError: '>' not supported between instances of 'Person' and 'Person'
This happens because comparing Person
objects this way is meaningless. You could compare the age, name, height, weight, or whatever. But the Python interpreter has no idea what our intention is.
To overcome this, you can specify what should happen when calling the greater-than operator (>
)on two Person
objects.
To do this, override the __gt__()
method in the Person
class.
For example, let’s make it possible to compare the Person
objects by their age
using the greater than operator:
class Person: def __init__(self, name, weight, height, age): self.name = name self.weight = weight self.height = height self.age = age def __str__(self): return f"This person is {self.name}. They weigh {self.weight} kilos and are {self.height} centimeters tall. They are {self.age} years old." def __repr__(self): return f"Person(name={self.name}, weight={self.weight}, height={self.height}, age={self.age})" def __gt__(self, other_person): return self.age > other_person.age
Now you can compare two objects with a greater-than operator:
soccer_player = Person("Jack", 80, 182, 30) tennis_player = Person("Rose", 60, 163, 23) print(soccer_player > tennis_player)
Output:
True
Now the greater-than comparison works.
However, now doing a less-than comparison fails. This is because you only specified how the greater-than comparison should work. To allow comparing with the less-than operator, you need to override the __lt__()
method.
Before we do that, let’s keep in mind there are other comparison operators too (<, >, <=, >=, ==, !=). If we override the behavior of one of them, we should override the rest of the operators to reflect the behavior.
This table shows you which method you need to override to customize the behavior of a comparison operator:
__eq__ | Equal |
__ne__ | Not equal |
__lt__ | Less than |
__gt__ | Greater than |
__le__ | Less than or equal |
__ge__ | Greater than or equal |
Let’s override each method in the above table to compare Person
objects by their age. Here is the updated version of the Person
class:
class Person: def __init__(self, name, weight, height, age): self.name = name self.weight = weight self.height = height self.age = age def __str__(self): return f"This person is {self.name}. They weigh {self.weight} kilos and are {self.height} centimeters tall. They are {self.age} years old." def __repr__(self): return f"Person(name={self.name}, weight={self.weight}, height={self.height}, age={self.age})" def __eq__(self, other_person): return self.age == other_person.age def __ne__(self, other_person): return not self.age == other_person.age def __lt__(self, other_person): return self.age < other_person.age def __gt__(self, other_person): return self.age > other_person.age def __ge__(self, other_person): return self.age >= other_person.age def __le__(self, other_person): return self.age <= other_person.age
Now you can make sure that the age-based comparisons work:
soccer_player = Person("Jack", 80, 182, 30) tennis_player = Person("Rose", 60, 163, 23) print(soccer_player == tennis_player) print(soccer_player != tennis_player) print(soccer_player < tennis_player) print(soccer_player > tennis_player) print(soccer_player >= tennis_player) print(soccer_player <= tennis_player)
Output:
False True False True True False
Class Inheritance Example
Given the Person class we implemented, let’s inherit it to a Student class. This is reasonable because each student is also a person:
class Student(Person): def __init__(self, name, weight, height, age, graduation_year): super().__init__(name, weight, height, age) self.graduation_year = graduation_year def greet(self): print(f"Hello, my name is {self.name}. I will graduate in {self.graduation_year}")
Now the student has all the properties the Person
class has. In addition, it has its own property graduation_year
and a greet()
method.
Now you can use this class:
student1 = Student("Sam", 80, 188, 23, 2023) student1.greet()
Output:
Hello, my name is Sam. I will graduate in 2023
And as this class inherits the comparison properties of the Person
class, you can also make comparisons with Student
objects:
math_student = Student("Alice", 80, 182, 28, 2022) physics_student = Student("Rose", 60, 163, 26, 2023) print(math_student == physics_student) print(math_student != physics_student) print(math_student < physics_student) print(math_student > physics_student) print(math_student >= physics_student) print(math_student <= physics_student)
Output:
False True False True True False