Understanding the Difference Between __new__ and __init__ in Python

In Python's object-oriented programming, __new__ is a rarely used method compared to __init__. While __init__ is commonly mistaken for a constructor, it's actually an initializer. The true instance creation happens in __new__.

class Publication(object):
    def __init__(self, name):
        super(Publication, self).__init__()
        self.name = name

# Create a publication instance
p = Publication('Python Cookbook')
print(p.name)

Key differences according to Python dcoumentation:

  • __new__ is called before instance creation and must return the instance
  • __init__ is called after instance creation to initialize attributes
class Publication(object):
    def __new__(cls, name):
        print('__new__ called')
        return super(Publication, cls).__new__(cls)
        
    def __init__(self, name):
        print('__init__ called')
        super(Publication, self).__init__()
        self.name = name
        
p = Publication('Python Cookbook')
print(p.name)

Output:

__new__ called
__init__ called
Python Cookbook

Practical applications of __new__:

1. Inheriting Immuatble Types

__new__ allows subclassing immutable types like str, int, or tuple.

2. Metaclass Implementation

In Django, __new__ can help access request objects in form validation:

class CustomForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        self.request = kwargs.pop('request')
        super(CustomForm, self).__init__(*args, **kwargs)
    
    def clean(self):
        # Access self.request here
        pass

# In admin.py
class CustomAdmin(admin.ModelAdmin):
    def get_form(self, request, *args, **kwargs):
        class FormMetaClass(CustomForm):
            def __new__(cls, *args, **kwargs):
                kwargs['request'] = request
                return CustomForm(*args, **kwargs)
        return FormMetaClass

Tags: python OOP magic-methods Django

Posted on Tue, 02 Jun 2026 17:27:29 +0000 by OzRedBoy