- Python Classes and Objects
- Create a Class
- Example
- Create Object
- Example
- The __init__() Function
- Example
- The __str__() Function
- Example
- Example
- Object Methods
- Example
- The self Parameter
- Example
- Modify Object Properties
- Example
- Delete Object Properties
- Example
- Delete Objects
- Example
- The pass Statement
- Adding Functions to Python Classes
- Common Mistake
- Instance Methods
- Summary
Python Classes and Objects
Almost everything in Python is an object, with its properties and methods.
A Class is like an object constructor, or a «blueprint» for creating objects.
Create a Class
To create a class, use the keyword class :
Example
Create a class named MyClass, with a property named x:
Create Object
Now we can use the class named MyClass to create objects:
Example
Create an object named p1, and print the value of x:
The __init__() Function
The examples above are classes and objects in their simplest form, and are not really useful in real life applications.
To understand the meaning of classes we have to understand the built-in __init__() function.
All classes have a function called __init__(), which is always executed when the class is being initiated.
Use the __init__() function to assign values to object properties, or other operations that are necessary to do when the object is being created:
Example
Create a class named Person, use the __init__() function to assign values for name and age:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
Note: The __init__() function is called automatically every time the class is being used to create a new object.
The __str__() Function
The __str__() function controls what should be returned when the class object is represented as a string.
If the __str__() function is not set, the string representation of the object is returned:
Example
The string representation of an object WITHOUT the __str__() function:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
Example
The string representation of an object WITH the __str__() function:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
Object Methods
Objects can also contain methods. Methods in objects are functions that belong to the object.
Let us create a method in the Person class:
Example
Insert a function that prints a greeting, and execute it on the p1 object:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def myfunc(self):
print(«Hello my name is » + self.name)
p1 = Person(«John», 36)
p1.myfunc()
Note: The self parameter is a reference to the current instance of the class, and is used to access variables that belong to the class.
The self Parameter
The self parameter is a reference to the current instance of the class, and is used to access variables that belongs to the class.
It does not have to be named self , you can call it whatever you like, but it has to be the first parameter of any function in the class:
Example
Use the words mysillyobject and abc instead of self:
class Person:
def __init__(mysillyobject, name, age):
mysillyobject.name = name
mysillyobject.age = age
def myfunc(abc):
print(«Hello my name is » + abc.name)
p1 = Person(«John», 36)
p1.myfunc()
Modify Object Properties
You can modify properties on objects like this:
Example
Delete Object Properties
You can delete properties on objects by using the del keyword:
Example
Delete the age property from the p1 object:
Delete Objects
You can delete objects by using the del keyword:
Example
The pass Statement
class definitions cannot be empty, but if you for some reason have a class definition with no content, put in the pass statement to avoid getting an error.
Adding Functions to Python Classes
Classes can be created as simply a collection of functions. The functions can be defined within the class exactly the same way that functions are normally created. In order to call these functions we need to call it from the class. So the example class called Greetings below takes a name and returns a greeting to the person calling the class.
class Greetings: def good_morning(name): print(f'Good morning ') def good_afternoon(name): print(f'Good afternoon ') def good_evening(name): print(f'Good evening ') Greetings.good_afternoon('John') Greetings.good_morning('Peter') Greetings.good_evening('Jane')
Out: Good afternoon John Good morning Peter Good evening Jane
Common Mistake
Although the class above behaves as we would expect. Let’s take the exact same class and add an __init__. See this article if you don’t know what the __init__ is.
class Greetings: def __init__(self): pass def good_morning(name): print(f'Good morning ') def good_afternoon(name): print(f'Good afternoon ') def good_evening(name): print(f'Good evening ') g = Greetings()
We have created an instance of the Greetings class named g. If we try to call the functions we defined within the class as follows:
TypeError: good_afternoon() takes 1 positional argument but 2 were given
It may not immediately be clear as to why this is happening. The TypeError returned above indicates that we have passed 2 arguments to the function, when it appears we have only passed one. Let’s try calling it without a name to see what happens:
g.good_afternoon() # out: Good afternoon
What is going on here?
When we create an instance of a class the first argument passed to the function is the instance itself. So the reason we are getting the TypeError is that the way Python is reading the g.good_afternoon(‘John’) function is g.good_afternoon(g, ‘John’) although this may seem confusing, it will become clear in the next section why this happens.
Instance Methods
Taking a new example class called Student, which takes a first name, last name, age and major.
class Student: def __init__(self, first, last, age, major): self.first = first self.last = last self.age = age self.major = major def profile(self): print(f"Student name ") print(f"Student age: ") print(f"Major: ") s = Student('Sally' , 'Harris', 20, 'Biology') s.profile()
Out: Student name Sally Harris Student age: 20 Major: Biology
When creating instance methods we must pass the self keyword, this takes care of the issue of the instance being passed to functions as the first argument. Let’s build on the current class and add enrollment functionality to show the ability of instance methods to interact with attributes.
class Student: def __init__(self, first, last, age, major): self.first = first self.last = last self.age = age self.major = major self.courses = [] def profile(self): print(f"Student name ") print(f"Student age: ") print(f"Major: ") def enrol(self, course): self.courses.append(course) print(f"enrolled in ") def show_courses(self): print(f" is taking the following courses") for course in self.courses: print(course) s = Student('Sally' , 'Harris', 20, 'Biology') s.enrol('Biochemistry I') # enrolled Sally in Biochemistry I s.enrol('Literature') # enrolled Sally in Literature s.enrol('Mathematics') # enrolled Sally in Mathematics s.show_courses() # SallyHarris is taking the following courses # Biochemistry I # Literature # Mathematics
All of the methods above have been bound to the instance (we named this instance s), we can check this by using the dir keyword on the instance to see all the attributes and methods bound to s.
Out: ['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'age', 'courses', 'enrol', 'first', 'last', 'major', 'profile', 'show_courses']
We can add a mix of instance bound functions and normal functions as defined at the beginning of the document. Below we add a method that prints the current academic year.
import datetime as dt class Student: def __init__(self, first, last, age, major): self.first = first self.last = last self.age = age self.major = major self.courses = [] def profile(self): print(f"Student name ") print(f"Student age: ") print(f"Major: ") def enrol(self, course): self.courses.append(course) print(f"enrolled in ") def show_courses(self): print(f" is taking the following courses") for course in self.courses: print(course) def academic_year(): now = dt.datetime.now() s = now.year, now.year -1 print(f"Current academic year is < str(s[0]) + '/' + str(s[1]) >")
However, we will still get an error if we try to call this new function from an instance, as we have established that calling methods/ functions from an instance always passes the instance itself in as the first argument. So If we wanted to call this academic year function we can do so as follows:
Student.academic_year() # returns: Current academic year is 2020/2019
A better way to handle this will be the topic of the next article on class & static methods.
Summary
— When calling a function from a class the syntax is ClassName.FunctionName()
— When calling a function bound to an instance of a class, the first argument passed in to the function is the instance itself. These are known as methods
— To access and call a method correctly we should pass self in as the first argument when writing the code for the method.
— These methods allow us to interact with attributes associated with the instance / class.