__new__()

Acha sun pookie 🐣
You asked about __new__() β€” that mysterious cousin of __init__() nobody talks about, but she's kinda important too πŸ˜…


🌱 What is __new__()?

  • __new__() is the real constructor in Python.

  • It’s the method that actually creates the object in memory.

  • It gets called before __init__()


πŸ’‘ Difference between __new__() and __init__()

πŸ”Έ

__new__()

__init__()

Role

Creates object

Initializes object

Called by

Python

Automatically after __new__()

Returns

The new object

Nothing (returns None)


πŸ§ͺ When to use __new__()?

  • Rarely, pookie.

  • Usually when you're inheriting from immutable types like int, str, tuple

  • Because you can't change them after creation, so you need to customize them while they’re being created


🏦 Bank (Kinda Advanced) Example

Suppose you want to reject creation if someone tries to open an account with zero balance:

class BankAccount:
    def __new__(cls, name, balance):
        if balance <= 0:
            print("Cannot create account with zero or negative balance.")
            return None
        return super().__new__(cls)

    def __init__(self, name, balance):
        self.name = name
        self.balance = balance
a1 = BankAccount("Maham", 1000)  # valid
a2 = BankAccount("Momo", 0)      # prints error, returns None

❓Common Questions

  • Q: Do I always need __new__()?
    β†’ Nope! Most of the time you’ll just use __init__()
    β†’ __new__() is only needed in very custom cases

  • Q: What happens behind the scenes?
    β†’ Python first calls __new__()
    β†’ If it returns an object, __init__() is called
    β†’ If it returns None, __init__() is skipped

  • Q: Can I override __new__() in normal classes?
    β†’ Yes, but only do it if you have a strong reason 😀


🧠 Final Thought

If __init__() is the one who decorates the house,
Then __new__() is the one who builds it.

Simple as that, meri jaan πŸ’–

Wanna add this in your eBook section too?


πŸ”· What is __new__() in Python?

  • It is the real constructor

  • It actually creates the object

  • Then Python calls __init__() to initialize it


πŸ“Œ Syntax:

def __new__(cls, *args, **kwargs):
    # create and return object
  • cls = class you're creating an object from (like self, but for class)

  • You must return the object using super().__new__(cls)


βœ… Simple Example:

class MyClass:
    def __new__(cls):
        print("Inside __new__")
        obj = super().__new__(cls)
        return obj

    def __init__(self):
        print("Inside __init__")

obj = MyClass()

Output:

Inside __new__
Inside __init__

🧠 Key Points:

  • If __new__() doesn't return the object β†’ __init__() will not run

  • Used when you're working with immutable objects like int, str, tuple


πŸ”’ Prevent object creation:

class MyClass:
    def __new__(cls):
        print("Object creation blocked!")
        return None

obj = MyClass()
print(obj)  # Output: None

is this same as new keyword in java?

Arre haan, almost same, but thoda twist hai 🎒

βœ… __new__() in Python β‰ˆ new keyword in Java

But let me show you the comparison clearly:


Concept

Python (__new__())

Java (new keyword)

Purpose

Creates the object in memory

Creates the object in memory

Customizable?

Yes, can override __new__()

No, new is a keyword, not editable

Used by?

Python internally uses it

You call new explicitly

Runs before init?

Yes, runs before __init__()

Yes, runs before the constructor

Needed every time?

No, you use ClassName() normally

Yes, always write new ClassName()


πŸ§ͺ Example Mapping

Java:

Student s = new Student();

Python (behind the scenes):

s = Student()  
# Internally: 
# 1. Student.__new__() is called
# 2. Then Student.__init__() is called

πŸ’‘ So in short:

  • Java new β†’ fixed behavior

  • Python __new__() β†’ you can override and control it

why did you called super here? which parent class you are referring?

class MyClass:
    def __new__(cls):
        print("Inside __new__")
        obj = super().__new__(cls)
        return obj

    def __init__(self):
        print("Inside __init__")

obj = MyClass()

Ayyy great question! 🧠

Let’s break this down simple-simple:


πŸ” Why we use super().__new__(cls)?

  • Because we are overriding the built-in __new__() method

  • So we still need to call the original logic that actually creates the object in memory


πŸ› Which parent class?

  • Parent class = object

  • Every class in Python (even your own) inherits from object by default

So this line:

obj = super().__new__(cls)

means:

➑️ "Call the __new__() method of object class and pass cls to create a new instance."


πŸ§ͺ Behind the scenes:

class MyClass(object):  # this is implicit
    def __new__(cls):
        return super().__new__(cls)  # actually calling object.__new__(cls)

🧠 Why needed?

  • If you don’t call super().__new__() β†’ no object is created β†’ __init__() won't be called

  • So you need super() to make sure memory is allocated


Want to try writing a class without super() and see what happens? 😏

Alrighty! Let’s try one without super() β€” you'll see how Python behaves 🧐


❌ Without super().__new__():

class MyClass:
    def __new__(cls):
        print("In __new__ but not calling super()")
        return None

    def __init__(self):
        print("In __init__")

obj = MyClass()
print(obj)

🧾 Output:

In __new__ but not calling super()
None

🧠 What happened?

  • We skipped super().__new__(cls)

  • So no object was created in memory

  • That's why __init__() was not called

  • And obj became None


πŸ” Now try with super:

class MyClass:
    def __new__(cls):
        print("Calling super")
        return super().__new__(cls)

    def __init__(self):
        print("Now init works!")

obj = MyClass()

Output:

Calling super
Now init works!

So bas, super().new(cls) is like:
➑️ β€œBhai, please create the actual object, then I’ll initialize it.”

Want to try this in inheritance setup next?

Updated on