Object-oriented programming (OOP) is a programming language model organized around “objects” rather than “actions” and data rather than logic. Historically, a program has been viewed as a logical procedure that takes input data, processes it, and produces output data. The programming challenge was seen as how to write the logic, not how to define the data. Object-oriented programming takes the view that what we really care about are the objects we want to manipulate rather than the logic required to manipulate them.
In Python everything is an object. As an object oriented language, Python provides two scopes for attributes: class attributes and instance attributes.
Class
A class may be defined as a blueprint for creating the objects. It defines all the properties like methods and attributes of the object, and how the object will behave and respond on certain actions.
Object
The object is an instance of any class, it is generally the implementation of the class.
Class Attribute
A class attribute is a Python Variable that belongs to a class rather than a particular object. This is shared between all other objects of the same class and is defined outside the constructor function __init__(self,…), of the class.
Instance Attribute
An instance attribute is a Python variable belonging to only one object. It is only accessible in the scope of the object and it is defined inside the constructor function of a class. For example, __init__(self,..).
An attribute is generally public, unless it starts with ‘_’ which would make it protected, or, more frequenty with ‘__’ which would make it private.
The below ExampleClass
is a basic Python class with two public attributes: class_attr
and instance_attr
.
instance_attr
is an instance attribute defined inside the constructor.class_attr
is a class attribute defined outside the constructor.
The instance_attr
is only accessible from the scope of an object. The class attribute (class_attr
) is accessible as both a property of the class and as a property of objects, as it is shared between all of them.
The Pythonic way
Python has a particular way to do getters and setters. The conventional method involves placing dunders for private methods/attributes and underscores for protected methods/attributes. The property and setter decorators are also used to signify methods as setters/getters.
class Monster:
counter = 0
def __init__(self, name):
Monster.counter += 1
self.name = name @property
def name(self):
return self.__name
@name.setter
def name(self, name):
self.__name = name
Differences between class and instance attributes
The biggest differences between class and instance attributes are that class attributes can be declared outside of methods and exist across different instances of classes. Instance attributes, however, use setter methods to instantiate clones of the parent class.
Class VS Instance Attributes?
Advantages of class attributes:
- All instances of the class inherit them from the class.
- They store data that is relevant to all the instances. For example, we could have a counter class attribute that increments every time we create a new instance and decrements every time we delete an instance. This way we can always keep track of how many instances of the same class we created.
Disadvantages of class attributes:
- It can get messy when you create an instance in which the value of the class attribute is different than the class attribute value, and then try to retrieve it through another instance. The behavior quickly becomes unexpected.
- It’s not possible to have two instances with different values. So you can’t use them to do different things on different objects.
Advantages of instance attributes:
- They are specific to an object and are easy to set and get thanks to properties.
- They are discarded once the instance is deleted, so they die with the instance they are associated with, which makes things clearer.
Disadvantages of instance attributes:
- They don’t allow keeping track of values in between instances.
- The fact that their values are lost on deletion is also a disadvantage in some cases where you want to keep a history of values for example.
How does Python deal with the object and class attributes using the __dict__
All instances have a __dict__ dictionary, which they use to store their attributes and their corresponding values.
The class istself has a __dict__ dictionary, containing class attributes, among other things.
When calling for an object attribute, Python will first look in the object dict, see if the attributes exists and would retrun its value if present.
Otherwise, it will search the Class attributes and would return the value of the desired attribute if it exists.
When calling for a class attribute, Python will only go through the existing attributes (in __dict__) if the class