Python self variable is used to bind the instance of the class to the instance method. We have to explicitly declare it as the first method argument to access the instance variables and methods. This variable is used only with the instance methods.
In most of the Object-Oriented programming languages, you can access the current object in a method without the need for explicitly having it as a method parameter. For example, we can use “this” keyword to access the current object in Java program. But, in Python we have to explicitly declare the object instance as “self” variable.
Python self is a keyword?
Python self variable is not a reserved keyword. But, it’s the best practice and convention to use the variable name as “self” to refer to the instance.
Python self variable Example
Let’s say we have a Dog class defined as below.
class Dog:
def __init__(self, breed):
self.breed = breed
def bark(self):
print(f'{self.breed} is barking.')
d = Dog('Labrador')
d.bark()
Output: Labrador is barking.
- The __init__() function is defined with two variables but when we are creating the Dog instance, we have to provide only one argument. The “self” is automatically assigned to the newly created instance of Dog class.
- The bark() method has only one argument – “self” – which gets bind to the Dog instance that calls this method. That’s why we are not passing any argument when calling the bark() method.
- If we have to access any instance variable in the function, we can use the dot operator.
Can we skip “self” variable?
What if the instance method doesn’t need to access instance variables. Can we skip the self variable in this case?
Let’s find out with a simple example.
class Dog:
def bark():
print('Barking')
d = Dog()
print("Done")
If you will run the above code, there won’t be any error. But, we are not calling the bark() method. Let’s see what happens when we try to call the bark() method.
d = Dog()
d.bark()

We are getting error as the bark() method accepts 0 argument but we provided 1. It’s because when we are calling d.bark()
, the “d” instance is automatically passed as the first argument to the bark() instance method.
But, if we access the bark() instance method through class reference then it will work fine. So, calling Dog.bark()
will not cause any errors.
Similar variables for Class Method and Static Method?
The same behavior is present with the Class methods too. The only difference is that the convention is to use “cls” as the variable name for the Class reference.
class Dog:
@classmethod
def walk(cls):
print('Dog is Walking')
Dog.walk()
However, it’s not required with a static method. Because, the static methods are self sufficient functions and they can’t access any of the class variables or functions directly.
Let’s look at a complete example with self and cls variables and a static method without any arguments.
class Dog:
def __init__(self, breed):
self.breed = breed
@classmethod
def walk(cls):
print('Dog is Walking')
# instance method
def bark(self):
print(f'{self.breed} is barking.')
@staticmethod
def add(x, y):
return x + y
Dog.walk()
d = Dog('Labrador')
d.bark()
print(Dog.add(10, 20))
Output:
Dog is Walking
Labrador is barking.
30
Quick Example to Break the Convention
This example is just to show you that it’s not mandatory to use the variable name as “self” and “cls”. In real programming, always stick to this convention.
class Dog:
@classmethod
def walk(myclass):
print('Dog is Walking')
# instance method
def bark(myobject):
print('Dog is Barking.')
Dog.walk()
d = Dog()
d.bark()
The “self” variable is bound to the current instance
The self variable gives us access to the current instance properties. We can confirm this with a simple example by creating two different instances of the Dog class.
class Dog:
def __init__(self, b):
self.breed = b
def bark(self):
print(f'{self.breed} is Barking.')
d1 = Dog('Labrador')
d2 = Dog('Husky')
d1.bark()
d2.bark()
Output:
Labrador is Barking.
Husky is Barking.
Why not make “self” variable implicit?
There had been a lot of suggestions to make the “self” variable a reserved keyword and implicitly available to the instance method. But, the suggestion was rejected by “Guido van Rossum”. You can read about them here and here.