In Python, self refers to the class object itself.
With self, you are able to access the attributes and methods of the class.
For instance, this Fruit class assigns a custom name and color to itself upon creation. These can then be accessed by the info() method:
class Fruit: def __init__(self, name, color): self.name = name self.color = color def info(self): print(self.color, self.name) banana = Fruit("Banana", "Yellow") banana.info()
To understand how this works, let’s dive deeper into the details of self in Python.
This guide is intended for someone who already knows about classes but the concept of self is a bit vague. If you are unfamiliar with Python classes, please check this guide.
The ‘self’ Keyword in Python
In Python, a class is a blueprint for creating objects.
Each Python object is representative of some class. In Python, an object is also called an instance of a class. If you want to create an object in Python, you need to have a class from which you can create one.
A typical Python class consists of methods that perform actions based on the attributes assigned to the object.
For instance, a Weight class could store kilograms and have the ability to convert them to pounds.
In a Python class, the self parameter refers to the class instance itself. This is useful because otherwise there would be no way to access the attributes and methods of the class.
Example: A Fruit Class
To understand self better, let’s take a look at a simple Fruit class. This Fruit class lets you create Fruit objects with a custom name and a color:
class Fruit: def __init__(self, name, color): self.name = name self.color = color def info(self): print(self.color, self.name)
Now you can create Fruit objects this way:
banana = Fruit("Banana", "Yellow") apple = Fruit("Apple", "Red")
And you can show info related to them:
Yellow Banana Red Apple
How Does ‘self’ Work in the Example?
Let’s examine how this Fruit class works.
When you create a new Fruit object, the __init__ method is called under the hood. It is responsible for creating objects. Let’s inspect the __init__ method of the Fruit class to see what is going on. It takes three arguments:
When you create a Fruit object, the __init__ method is called with the custom name and color. Notice how you do not need to pass self as an argument. Python does it automatically for you.
So, when you call banana = Fruit(“Banana”, “Red”):
- The __init__ method starts initializing the banana object with the given name and color arguments.
- It creates new attributes self.name and self.color and stores the input name and color to them.
- After this, it is possible to access the name and the color attributes of the banana anywhere in the object via self.name or self.color.
Let’s also see what happens when you call banana.info().
When you call banana.info(), Python automatically passes the self into the method call as an argument under the hood. The info() method can then use self to access the name and color attributes of the object. Without self, it would not be able to do that.
Store Anything to Self in Python
Previously, you saw how the self parameter can be used to store attributes to the objects.
More specifically, you saw the typical approach where you pass __init__ method arguments and assign them to self using the same name:
def __init__(self, name, color): self.name = name self.color = color
This may raise the question “Do the argument names have to equal to what is assigned to the self?” The answer is no.
Similar to how you can create any variable anywhere in Python, you can assign any attributes to an object via self.
This means you can store any values with any names to self. They do not even have to be given as arguments in the __init__ function.
For example, let’s create a class Point that represents a point in 3D space. Let’s initialize the Point objects in the origin without asking for the points as arguments upon initialization.
To do this, assign x, y, and z values of 0 to self in the __init__ method:
class Point: def __init__(self): self.x = 0 self.y = 0 self.z = 0
Now you can create Point objects to the origin:
p = Point() print(p.x, p.y, p.z)
0 0 0
The point here is to demonstrate how you can freely add any attributes to an object’s self property.
A Method without ‘self’ Argument in a Python Class
In Python, a method needs the self argument. Otherwise, it doesn’t know the class it belongs to and is unable to perform actions on it.
To see what happens if a method doesn’t accept the self argument, let’s leave self out from the info() method:
class Fruit: def __init__(self, name, color): self.name = name self.color = color def info(): print(self.color, self.name) banana = Fruit("Banana", "Yellow") banana.info()
Traceback (most recent call last): File "main.py", line 10, in <module> banana.info() TypeError: info() takes 0 positional arguments but 1 was given
The last line suggests that the info() method takes no arguments, but we gave it one. But based on the above code, it seems you didn’t give any arguments. So why does the interpreter still think you gave it some?
Even though you do not give the info() method any arguments, Python automatically tries to inject self into the call. This is because Python knows all methods in a class need to have a reference to the class itself to work properly. But in our implementation of info(), there’s no argument self. Thus passing self argument into it behind the scenes will fail.
This shows you that you need to use the self argument in methods.
Proof That Self Refers to the Object Itself
For the sake of clarity, let me prove that the self indeed refers to the object itself.
To do this, let’s check the memory locations of self and a Fruit object.
In Python, you can check the memory address of an object with the id() function. (Here I have simplified the Fruit class to make it easier to digest):
class Fruit: def __init__(self): print("Self address =", id(self)) fruit = Fruit() print("Object address =", id(fruit))
Self address = 140243905604576 Object address = 140243905604576
As you can see, the memory addresses are equal. This shows you that self inside the Fruit class points to the same address as the fruit object you just created. In other words, the self parameter really refers to the object itself.
Self Is Not a Reserved Keyword in Python
Notice that self is not a reserved keyword in Python. You could use any name you like instead as long as there’s one.
For instance, let’s change the implementation of the Fruit class from earlier sections. This time, let’s use the name this instead of self:
class Fruit: def __init__(this, name, color): this.name = name this.color = color def info(this): print(this.color, this.name) banana = Fruit("Banana", "Yellow") apple = Fruit("Apple", "Red")
This code works the exact same way as the one that used self.
But because self is so commonly used among Python developers, it’s advisable not to use anything else. You are unlikely to encounter anything else than self when working with classes in Python.
Today you learned what self does in a Python class.
To recap, self in Python refers to the object itself. It is useful because this way the class knows how to access its own attributes and methods.
When you create an object, the __init__ method is invoked. In this method, you typically assign attributes to the class instance via self.
Notice how the self is not a reserved keyword. You could use whatever instead of self, as long as you pass it as the first argument for each method of the class. However, self is so commonly used that you should not use anything else, even though it is possible.
Thanks for reading. I hope you found what you were looking for. Happy coding!