DEV Community

Jaimin Bariya
Jaimin Bariya

Posted on

Python's Magic Methods

1 -> __new__(cls) Method

The __new__ method is called when a new object is created in Python. It's responsible for creating and returning the new instance of the class. This method is usually used when you want to customize object creation, such as for singleton patterns, caching, or managing memory.

When is __new__ Called?

The __new__ method is called before __init__ and is used to create the new object. Here's the typical order of events when you create a new object:

  1. __new__: Creates the object (memory allocation).
  2. __init__: Initializes the object (setting up attributes).

Use Cases for __new__:

  1. Singleton Pattern: The Singleton pattern ensures that only one instance of a class exists. In this case, __new__ checks if an instance already exists and reuses it, instead of creating a new one.
   class Singleton:
       _instance = None

       def __new__(cls):
           if cls._instance is None:
               cls._instance = super(Singleton, cls).__new__(cls)
           return cls._instance

   s1 = Singleton()
   s2 = Singleton()
   print(s1 is s2)  # True, both are the same instance
Enter fullscreen mode Exit fullscreen mode
  1. Caching Objects: If you want to cache objects based on certain conditions, you can use __new__ to check if an object already exists (e.g., in a dictionary) before creating a new one. This can help optimize memory usage.
   class CachedObject:
       _cache = {}

       def __new__(cls, value):
           if value in cls._cache:
               return cls._cache[value]
           obj = super().__new__(cls)
           cls._cache[value] = obj
           return obj

   obj1 = CachedObject("hello")
   obj2 = CachedObject("hello")
   print(obj1 is obj2)  # True, the same object is reused
Enter fullscreen mode Exit fullscreen mode
  1. Memory Management:
    If you want to control the memory allocation of objects (e.g., to optimize memory usage or manage large objects), __new__ can be used to customize how objects are created.

  2. Immutable Objects:
    __new__ is often used with immutable objects like tuples and strings. For instance, when you want to create a custom immutable object, you would override __new__ to ensure it’s properly created.

   class MyTuple(tuple):
       def __new__(cls, *args):
           return super().__new__(cls, args)

   t = MyTuple(1, 2, 3)
   print(t)  # (1, 2, 3)
Enter fullscreen mode Exit fullscreen mode

In Summary:

  • __new__ is called when an object is being created and is responsible for returning the instance of the class.
  • It is useful for optimizing object creation, implementing patterns like Singleton, managing object caching, or even customizing the memory allocation process.

Top comments (0)