I tried learning OOP from many video tutorials and documentation but I'm not understanding why we really need it or what is the use of it.
So it would be really helpful if someone could explain to me like a child what is the need for self and init in python.
Also, If you could tell me how did you fully grasp the concept of OOP in Python that would be really beneficial to me.
Thank You.
Python class __init__ and self
When do you use 'self' in Python? - Stack Overflow
python - What is the purpose of the `self` parameter? Why is it needed? - Stack Overflow
object oriented - Why do you need "self." in Python to refer to instance variables? - Software Engineering Stack Exchange
Adding an answer because Oskarbi's isn't explicit.
You use self when:
- Defining an instance method. It is passed automatically as the first parameter when you call a method on an instance, and it is the instance on which the method was called.
- Referencing a class or instance attribute from inside an instance method. Use it when you want to call a method or access a name (variable) on the instance the method was called on, from inside that method.
You don't use self when
- You call an instance method normally. Using Oskarbi's example, if you do
instance = MyClass(), you callMyClass.my_methodasinstance.my_method(some_var)not asinstance.my_method(self, some_var). - You reference a class attribute from outside an instance method but inside the class definition.
- You're inside a staticmethod.
These don'ts are just examples of when not to use self. The dos are when you should use it.
Use self to refer to instance variables and methods from other instance methods. Also put self as the first parameter in the definition of instance methods.
An example:
class MyClass(object):
my_var = None
def my_method(self, my_var):
self.my_var = my_var
self.my_other_method()
def my_other_method(self):
# do something...
The reason you need to use self is because Python does not use special syntax to refer to instance attributes. Python decided to do methods in a way that makes the instance to which the method belongs be passed automatically but not received automatically, the first parameter of methods is the instance the method is called on. That makes methods entirely the same as functions and leaves the actual name to use up to you (although self is the convention, and people will generally frown at you when you use something else.) self is not special to the code, it's just another object.
Python could have done something else to distinguish normal names from attributes -- special syntax like Ruby has, or requiring declarations like C++ and Java do, or perhaps something yet more different -- but it didn't. Python's all for making things explicit, making it obvious what's what, and although it doesn't do it entirely everywhere, it does do it for instance attributes. That's why assigning to an instance attribute needs to know what instance to assign to, and that's why it needs self.
Let's say you have a class ClassA which contains a method methodA defined as:
class ClassA:
def methodA(self, arg1, arg2):
... # do something
and objectA is an instance of this class.
Now when objectA.methodA(arg1, arg2) is called, python internally converts it for you as:
ClassA.methodA(objectA, arg1, arg2)
The self variable refers to the object itself.
1) Why is self required as an explicit parameter in method signatures?
Because methods are functions and foo.bar(baz) is just syntactic sugar for bar(foo, baz). Classes are just dictionaries where some of the values are functions. (Constructors are also just functions, which is why Python doesn't need new) You can say that Python makes it explicit that objects are built from simpler components. This is in accordance with the "explicit is better than implicit"-philosophy.
In contrast, in Java objects really are magic and cannot be reduced to simpler components in the language. In Java (at least until Java 8) a function is always a method owned by an object, and this ownership cannot be changed due to the static nature of the language. Therefore there is no ambiguity about what this refers to, so it makes sense to have it implicitly defined.
JavaScript is an example of a language that has an implicit this like Java, but where functions can exist separately from objects like in Python. This leads to a lot of confusion about what this refers to when functions are passed around and called in different contexts. Many instinctively think this must refer to some intrinsic property of the function, while it is actually purely determined by the way the function is called. I believe having this as an explicit parameter like in Python would make this much less confusing.
Some other benefits of the explicit self-parameter:
Decorators are just functions which wrap other functions. Since methods are just functions, decorators work just as fine on methods. If there were some kind of implicit self, decorators would not work transparently on methods.
Classmethods and static methods do not take an instance parameter. Classmethods take a class as the first argument (typically called
cls). The explicitselforclsparameters make it much clearer what is going on, and what you have access to in the method.
2) Why must instance variables always be qualified with"self.?
In Java, you don't need to prefix member variables with "this.", but in Python "self." is always required. The reason is that Python does not have an explicit syntax for declaring variables, so there would be no way to tell if x = 7 is supposed to declare a new local variable or assign to a member variable. Specifying self. solves this ambiguity.
There is a rather simple reason that AFAIK hasn't really been touched upon in the cross-site duplicate, nor here: Python started out as a procedural language. It was based on ABC, also a procedural language.
Object-Orientation was added later, and when it was added, Guido van Rossum wanted to add the minimal amount of features possible, in order to keep the design of Python simple. Python already had dicts and functions, so why add something entirely new to the language, when an object can simply be a dict of slots and a class can simply be a dict of functions? A method can be interpreted as a partially-applied function that closes over a single distinguished argument. And that's precisely how methods are implemented in Python: they aren't. They are just functions which receive an extra distinguished argument.