Python Object Creation: __new__ vs __init__
Learn the roles of __new__ and __init__ in Python object creation and initialization.
In Python, object-oriented programming revolves around creating and managing objects. Two special methods, __new__ and __init__, play vital roles in this process. However, their purposes are often confused by beginners and even some experienced developers.
While __init__ is widely used to initialize objects, __new__ is less commonly encountered, but equally important. Understanding their differences and how they work together is essential for mastering Python’s object model.
Today, in this article explores the roles of __new__ and __init__, their differences, and practical use cases where each shines.
Let’s dive in!
Hi, my name is CyCoderX. I write articles for everyone to enjoy, and I’d love your support by following me, clapping and highlighting parts of my article!
What is __new__?
The __new__ method in Python is responsible for creating a new instance of a class. It is called before __init__ and is typically used when you need to control how objects are created, such as in custom object creation scenarios.
Key Points about __new__:
- Purpose: Allocates memory and returns a new instance of the class.
- Called Before
__init__: Without a properly created object from__new__, the__init__method will not be called. - Defined in the Base Class: By default, it is inherited from
object.
Syntax of __new__:
class MyClass:
def __new__(cls, *args, **kwargs):
print("Creating a new instance of MyClass")
instance = super().__new__(cls)
return instanceExample of Using __new__:
class CustomClass:
def __new__(cls):
print("Creating a new CustomClass object")
instance = super().__new__(cls)
return instance
obj = CustomClass()Output:
Creating a new CustomClass objectWhy Use __new__?
You would typically use __new__ when:
- Creating immutable objects like tuples or strings.
- Implementing design patterns such as singletons.
- Customizing object allocation behavior.
What is __init__?
The __init__ method in Python is responsible for initializing an instance of a class. It is called after __new__ and is typically used to set up the initial state of an object by assigning values to its attributes.
Key Points about __init__:
- Purpose: Prepares the created object by initializing attributes or performing setup tasks.
- Called After
__new__: It operates on an already created instance. - Does Not Return Anything: Unlike
__new__, it does not allocate memory or return a new object.
Syntax of __init__:
class MyClass:
def __init__(self, name, age):
print("Initializing MyClass instance")
self.name = name
self.age = ageExample of Using __init__:
class Person:
def __init__(self, name, age):
print(f"Initializing Person: {name}, {age}")
self.name = name
self.age = age
person = Person("Alice", 30)Output:
Initializing Person: Alice, 30Why Use __init__?
You use __init__ for:
- Setting initial values for attributes.
- Performing setup tasks specific to the object.
- Ensuring the object is in a consistent state before it’s used.
Connect with me on LinkedIn and X to stay ahead of industry trends and for more tips and tricks!
Key Differences Between __new__ and __init__
Here’s a breakdown of the differences between __new__ and __init__:
- Purpose:
__new__is used to create a new instance of a class. It allocates memory and returns the instance. On the other hand,__init__is used to initialize the attributes of an already created instance. - When They Are Called:
__new__is called first, during the object creation phase, while__init__is called immediately afterward to perform initialization tasks. - Return Value:
__new__must return an instance of the class, either a new one or a previously existing one. In contrast,__init__does not return anything. - Use Cases:
You use__new__when you need to customize how objects are created, such as implementing singletons or working with immutable objects.__init__, on the other hand, is used to set initial values for attributes or perform object-specific setup tasks. - Customization:
__new__is typically overridden when subclassing immutable types liketupleorstr, while__init__is defined in most classes to configure instance-specific details.
When to Use __new__ Over __init__
Although __init__ is more commonly used, there are specific scenarios where __new__ is necessary:
- Immutable Objects:
Since immutable objects like strings and tuples cannot be modified after they are created, you must use__new__to customize their creation.
Example:
class CustomTuple(tuple):
def __new__(cls, iterable):
print("Creating a CustomTuple")
return super().__new__(cls, iterable)
obj = CustomTuple([1, 2, 3])
print(obj) # Output: (1, 2, 3)- Singleton Pattern:
To ensure that only one instance of a class is created, you can use__new__.
Example:
class Singleton:
_instance = None
def __new__(cls, *args, **kwargs):
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
obj1 = Singleton()
obj2 = Singleton()
print(obj1 is obj2) # Output: True- Custom Object Creation:
If you need to modify the instance creation process, such as returning a cached instance or modifying class attributes,__new__is the method to override.
Practical Examples Comparing __new__ and __init__
Example 1: Customizing Object Creation with __new__
In this example, we use __new__ to modify the creation process:
class PositiveInteger(int):
def __new__(cls, value):
if value < 0:
raise ValueError("Value must be positive")
return super().__new__(cls, value)
num = PositiveInteger(5)
print(num) # Output: 5
# num = PositiveInteger(-5) # Raises ValueErrorHere, __new__ ensures that only positive integers are created, rejecting negative values during the object creation phase.
Example 2: Initializing Object Attributes with __init__
In this example, we use __init__ to set up instance-specific attributes:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
person = Person("Alice", 30)
print(person.name) # Output: Alice
print(person.age) # Output: 30__init__ is used to initialize the attributes name and age for each instance of the Person class.
Conclusion
In Python, __new__ and __init__ serve distinct but complementary roles in object-oriented programming. __new__ is responsible for creating new instances of a class, while __init__ initializes these instances with specific values or configurations.
Get CyCoderX’s stories in your inbox
Join Medium for free to get updates from this writer.
Use __new__ when you need to customize the object creation process, such as working with immutable objects or implementing design patterns like singletons. For most everyday scenarios, __init__ suffices to set up instance-specific attributes and perform initialization tasks.
Understanding the differences between these methods allows you to leverage Python’s object model effectively and write more powerful, flexible code.
Final Words:
Thank you for taking the time to read my article. Article first published on Medium by CyCoderX.
Hi, I’m CyCoderX! An engineer passionate about sharing knowledge, I write articles about Python, SQL, Data Science, Data Engineering and more!
Please consider supporting me by:
- Clapping 50 times for this story
- Leaving a comment telling me your thoughts
- Highlighting your favorite part of the story
Socials
In Plain English 🚀
Thank you for being a part of the In Plain English community! Before you go:
- Be sure to clap and follow the writer ️👏️️
- Follow us: X | LinkedIn | YouTube | Discord | Newsletter | Podcast
- Create a free AI-powered blog on Differ.
- More content at PlainEnglish.io









