All about Pythonic Class: The Life Cycle

All about Pythonic Class: The Life Cycle

Python Data Model (Objects, Types, and Values): We have shown How to write a basic class, What is the relation between class and object, and the differences between new-style and old-style class. We will start this chapter from where we left the previous one

This is the second part of “All about Pythonic Class”. Now, our “Python Data Model” series —

  1. Objects, Types, and Values; Python Data Model
  2. All about Pythonic Class: The Birth and Style; Python Data Model
  3. All about Pythonic Class: The Life Cycle; Python Data Model

In the previous chapter, we have shown How to write a basic class, What is the relation between class and object, and the differences between new-style and old-style class. We will start this chapter from where we left the previous one-

What actually happens when we define a class

So what happens when we declare a class? How does the Python interpreter interpret it?

Two special methods are called under the hood when we call a class to form an object.

  • First, the interpreter calls **new** method which is the ‘true’ constructor of a class. This special method then creates an object, in an unnamed location into the memory, with the correct type.
  • Then **init** is called to initialize the class object with the previous object created by **new. Most of the times we don’t need to declare a __new__** special method without an obvious reason. It mainly takes place in the background. Instantiating an object with **init** is the most common and standard practice that is sufficient to serve most of our purposes.

It is an intricate process that creates a class behind the scene. It will also need in-depth knowledge of the design of the Python interpreter and the implementation of the language at its core. For the sake of simplicity, we will describe the process from a high-level point of view and write hypothetical or pseudo-codes of the backend process.

When we call a class to form an object, the interpreter calls type. It takes three parameters--

type(classname, superclass, attribs) or

type("", (), {})

where the class name is the string representation of the declared class, the superclass is the tuple representation of class(es) from which our class will inherit properties and attributes is the dictionary representation of the class.__dict__.

Let's declare a class normally

class Footballer():
    game = "Football"

    def __init__(self, name, club):
        self.name = name
        self.club = club

    def a_method(self):
        return None

print(Footballer.__dict__)    

## Output
'''
{'__module__': '__main__', 'game': 'Football', '__init__': <function Footballer.__init__ at 0x7f10c4563f28>, 'a_method': <function Footballer.a_method at 0x7f10c45777b8>, '__dict__': <attribute '__dict__' of 'Footballer' objects>, '__weakref__': <attribute '__weakref__' of 'Footballer' objects>, '__doc__': None}
'''

Now we will write the same type of class using type metaclass

def outer_init(self, name, club):
    self.name = name
    self.club = club

Footballer1 = type("Footballer1", (), {"game":"Soccer",  "__init__": outer_init, "b_method": lambda self: None})print(Footballer1.__dict__)  
print(Footballer1.game)

## Output
'''
{'game': 'Soccer', '__init__': <function outer_init at 0x7f10c4510488>, 'b_method': <function <lambda> at 0x7f10c4510f28>, '__module__': '__main__', '__dict__': <attribute '__dict__' of 'Footballer1' objects>, '__weakref__': <attribute '__weakref__' of 'Footballer1' objects>, '__doc__': None}Soccer
'''

Aha! we have just made a regular user-defined class using type metaclass!! What actually is going on here?

When type is called, its __call__ method is executed that runs two more special methods--

  1. type.__new__(typeclass, classname, superclasses, attributedict)the constructor
  2. type.__init__(cls, classname, superclasses, attributedict) the initiator/initializer

__new__(cls, [...) Special method __new__ is the very first method that is called when an object is created. Its first argument is the class itself following other arguments needed to form it. This function is rarely used and by default called by the interpreter during object creation.

__init__(self, [...) The initializer special method initializes a class and gives the default attributes of an object. This method takes an object as the first parameter following other arguments for it. This is the most frequently used special method in the Python world.

The following pseudo-code shows how the Python interpreter creates an object from a class. Remember we have omitted the low-level things done by the interpreter for the sake of a basic understanding. Have a look at the self-explanatory code instructions

class Bar():
    def __init__(self, obVar):
        self.obVar = obVar

>>> obj = Bar("a string") ----------------[1]## putting  object parameter into a temporary variable
>>> tmpVar = Bar.__new__(Bar, "another string") 
>>> type(tmpVar)
>>> __main__.Bar>>> tmpVar.obVar -------------------------[2]## the class is not initialised yet 
## It will throw errors>>> AttributeError Traceback (most recent call last)
....
AttributeError: 'Bar' object has no attribute 'obVar'
------------------------------------------------------## initialise a temporary variable 
>>> tmpVar.__init__("a string") ---------------[3]
>>> tmpVar.obVar
>>> 'another string'>>> obVar = tmpVar 
>>> obVar.obVar
>>> 'another string' 

The Obj is behaving as we expected [1]. But, when we createdtmpVar by calling Bar.__new__ and trying to access obVar, it throws an error [2]. Thus, we need to initialize with the __init__ and after that, it will work nicely as the previous variable [3] .

P.S.- The method with double underscores on both sides of his name is known as special methods or magic methods. The special method is an “implementation detail” or low-level detail of CPython. Why do we call them magic methods? Because these methods add “magic” to our class. We will have two separate chapters for magic methods.

python programming developer web-development machine-learning

Bootstrap 5 Complete Course with Examples

Bootstrap 5 Tutorial - Bootstrap 5 Crash Course for Beginners

Nest.JS Tutorial for Beginners

Hello Vue 3: A First Look at Vue 3 and the Composition API

Building a simple Applications with Vue 3

Deno Crash Course: Explore Deno and Create a full REST API with Deno

How to Build a Real-time Chat App with Deno and WebSockets

Convert HTML to Markdown Online

HTML entity encoder decoder Online

Hire Machine Learning Developers in India

We supply you with world class machine learning experts / ML Developers with years of domain experience who can add more value to your business.

Python Tutorial - Learn Python for Machine Learning and Web Development

Learn Python for Machine Learning and Web Development. Can Python be used for machine learning? Python is widely considered as the preferred language for teaching and learning ML (Machine Learning). Can I use Python for web development? Python can be used to build server-side web applications. Why Python is suitable for machine learning? How Python is used in AI? What language is best for machine learning?

Hire Python Developers

Are you looking for experienced, reliable, and qualified Python developers? If yes, you have reached the right place. At **[HourlyDeveloper.io](https://hourlydeveloper.io/ "HourlyDeveloper.io")**, our full-stack Python development services...

How To Plot A Decision Boundary For Machine Learning Algorithms in Python

How To Plot A Decision Boundary For Machine Learning Algorithms in Python, you will discover how to plot a decision surface for a classification machine learning algorithm.

Hire Python Developers India

Looking to build robust, scalable, and dynamic responsive websites and applications in Python? At **[HourlyDeveloper.io](https://hourlydeveloper.io/ "HourlyDeveloper.io")**, we constantly endeavor to give you exactly what you need. If you need to...