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__()
πΈ |
|
|
|---|---|---|
Role | Creates object | Initializes object |
Called by | Python | Automatically after |
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 returnsNone,__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 (likeself, 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 ( | Java ( |
|---|---|---|
Purpose | Creates the object in memory | Creates the object in memory |
Customizable? | Yes, can override | No, |
Used by? | Python internally uses it | You call |
Runs before init? | Yes, runs before | Yes, runs before the constructor |
Needed every time? | No, you use | Yes, always write |
π§ͺ 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
objectby 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
objbecameNone
π 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?