Object-Oriented Programming in Python — Corey Schafer & DataCamp | by Md Arman Hossen | Towards Data Science

Object-oriented programming (OOP) is a programming paradigm based on “object” which is a way to define something in a programming language containing variable as “field/attributes” and functions as “method”. OOP allows programmers to create their own objects that have methods and attributes. OOP allows a user to create their own object which is repeatable and organized.
In this article, I’ve tried to summarize my ideas on OOP in python. I would like to thank Jose Marcial Portilla, DataCamp Team and Corey Schaffer for their amazing descriptive tutorials. It helps me a lot. I’ll try to add a GitHub repository ASAP for this.
Class is a reusable chunk of code that has methods and variables. Precisely class is a template for an object. Classes allow us to logically group our data and functions in a way that’s easy to reuse and also easy to build upon if need be. Here data and functions are called attributes and methods. In the below figure a class Datashell is defined without passing any attributes. passdoesn’t do anything, it's just a placeholder.
selfrepresents the instance of the object itself. Most object-oriented languages pass this as a hidden parameter to the methods. Anything can be used in place of selfbut to make it sensible to others we should use self. To print a method we need to use parentheses()at the end. If we skip()then it only prints the method instead of the return value. Class, method, and instances are being described clearly describe through the below figure.
<blockquote>
In OOP, variables at the class level are referred to as class variables, whereas variables at the object level are called instance variables. In the following figure general form and an example of a class variable is delineated. Here ‘spam’ is defined as class variable data which is being used as instance variable later in several methods.
If we change the class variable through calling class then the value will be changed in all places whereas if we change variable through instances then only that vale will be changed. Suppose if we change the value of data to “not spam” then all values of instances including data will be changed but if we change the instance variable in any method then it will be only within that method.
Regular methods automatically pass the instances as the first argument and we call it self. Class methods automatically pass the class as the first argument and we call it cls . Static methods don’t pass anything automatically, they don’t pass instances or class, they behave just like a regular function and they have some logical connection with the class. The methods mentioned in all the above examples are regular methods. But for class method and static method we need to mention it [@classmethod / @staticmethod ] before apply.
@classmethoddef set_raise(cls,amount):    cls.raise = amount
Inheritance allows us to inherit attributes and methods from a parent class. it's the ability to reuse and reduce complexity. We can create subclasses and get all the functionality of our parent class and then we can overwrite or add completely new functionality without affecting the parent class in any way. Inheritance is being described clearly through the below example.
Now if we want to copy any attribute from another class and add more attributes on it then we can do it following ways. We can either use super() whereselfshould be avoided or we can call the class directly mentioningself.
class hi(hello):    def __init__(self, name, age):        super().__init__(data)or      "hello.__init__(self, data)"
Special methods allow us to emulate some built-in behavior within python. By defining our own special methods we’ll be able to change some of the built-in behavior and operations. Special methods are always surrounded by __method__. A lot of people call them double underscore Dunder. Here are some common special methods:
__init__(self) : implicitly called when we create our objects and it sets all attributes.
__repr__(self) : unambiguous representation of the object and should be used for debugging and logging
__str__(self) : readable representation of an object and meant to be used as a display to the end-user.
__add__(self) : to add objects.
__len__(self) : to generate the length of objects.
Property decorator allows us to define a method but we can access it like an attribute. In the following example name is a method but we can call it like an attribute.
That’s the end of my knowledge about OOP in python. I’ve tried my best to describe in detail within my limit. It’ll be highly appreciated if you can make comments or critics on this. I’m not from CS background and still, I’m learning each and every day. If you like this article then you can check my other article on Markdown Cells — Jupyter Notebook.