In Python, everything is an object, and can be handled as such. This is what ismeant when we say, for example, that functions are first-class objects.Functions, classes, strings, and even types are objects in Python: like anyobject, they have a type, they can be passed as function arguments, and theymay have methods and properties. In this understanding, Python is anobject-oriented language.
However, unlike Java, Python does not impose object-oriented programming as themain programming paradigm. It is perfectly viable for a Python project to notbe object-oriented, i.e. to use no or very few class definitions, classinheritance, or any other mechanisms that are specific to object-orientedprogramming.
There are some reasons to avoid unnecessary object-orientation. Definingcustom classes is useful when we want to glue together some state and somefunctionality. The problem, as pointed out by the discussions about functionalprogramming, comes from the “state” part of the equation.
In some architectures, typically web applications, multiple instances of Pythonprocesses are spawned to respond to external requests that can happen at thesame time. In this case, holding some state in instantiated objects, whichmeans keeping some static information about the world, is prone to concurrencyproblems or race conditions. Sometimes, between the initialization of the stateof an object (usually done with the method) and the actual useof the object state through one of its methods, the world may have changed, andthe retained state may be outdated. For example, a request may load an item inmemory and mark it as read by a user. If another request requires the deletionof this item at the same time, it may happen that the deletion actually occursafter the first process loaded the item, and then we have to mark as read adeleted object.
Another way to say the same thing is to suggest using functions and procedureswith as few implicit contexts and side-effects as possible. A function’simplicit context is made up of any of the global variables or items in thepersistence layer that are accessed from within the function. Side-effects arethe changes that a function makes to its implicit context. If a function savesor deletes data in a global variable or in the persistence layer, it is said tohave a side-effect.
Carefully isolating functions with context and side-effects from functions withlogic (called pure functions) allow the following benefits: