Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
__new__ in Python
The __new__ method in Python is a special method that controls object creation. Unlike __init__ which initializes an object, __new__ is responsible for actually creating and returning a new instance of a class before __init__ is called.
Understanding __new__
The __new__ method is a static method that belongs to the class rather than instances. It's called automatically when creating objects and is particularly useful when you need to control the object creation process, implement design patterns like Singleton, or work with immutable classes.
Basic Example Input Validation
Here's how to use __new__ to validate input during object creation ?
class Person:
def __new__(cls, name):
if not name:
raise ValueError("Name cannot be empty.")
return super().__new__(cls)
def __init__(self, name):
self.name = name
# Valid instance
john = Person("John")
print(john.name)
# Invalid instance
try:
empty_person = Person("")
except ValueError as e:
print(e)
John Name cannot be empty.
Implementing Singleton Pattern
The __new__ method is perfect for implementing the Singleton pattern, ensuring only one instance exists ?
class Singleton:
_instance = None
def __new__(cls, *args, **kwargs):
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
def __init__(self, value):
if not hasattr(self, 'initialized'):
self.value = value
self.initialized = True
# Both variables reference the same instance
singleton1 = Singleton("First")
singleton2 = Singleton("Second")
print(singleton1 is singleton2)
print(singleton1.value)
True First
Customizing Immutable Classes
When working with immutable classes, __new__ allows customization before the object becomes immutable ?
class UpperString(str):
def __new__(cls, value):
if not isinstance(value, str):
value = str(value)
return super().__new__(cls, value.upper())
# Create custom string instances
text1 = UpperString("hello world")
text2 = UpperString(42)
print(text1)
print(text2)
print(type(text1))
HELLO WORLD 42 <class '__main__.UpperString'>
Key Differences: __new__ vs __init__
| Aspect | __new__ | __init__ |
|---|---|---|
| Purpose | Creates and returns instance | Initializes instance attributes |
| When called | Before object exists | After object is created |
| Return value | New instance | None |
| First parameter | cls (class) | self (instance) |
Best Practices
Always call super().__new__(): Ensure proper inheritance and resource allocation by calling the parent class's __new__ method.
Use sparingly: Only use __new__ when you need precise control over object creation. For most cases, __init__ is sufficient.
Consider alternatives: Factory functions or class methods might be simpler solutions for many use cases.
class Point:
def __new__(cls, x, y):
# Validate coordinates
if not isinstance(x, (int, float)) or not isinstance(y, (int, float)):
raise TypeError("Coordinates must be numeric")
return super().__new__(cls)
def __init__(self, x, y):
self.x = x
self.y = y
def __repr__(self):
return f"Point({self.x}, {self.y})"
# Valid point
point = Point(3, 4)
print(point)
# Invalid point
try:
invalid_point = Point("a", "b")
except TypeError as e:
print(e)
Point(3, 4) Coordinates must be numeric
Conclusion
The __new__ method provides powerful control over object creation in Python. Use it for implementing design patterns like Singleton, validating inputs before object creation, or customizing immutable classes. Remember to always call super().__new__() and use this feature judiciously.
