Fundamentals 16 min read

Unlocking Python’s __new__: Build Singletons, Multitons, and Cache Efficiently

This article explains Python’s special __new__ constructor, shows how to override it to create singleton and multiton patterns with caching, and demonstrates the impact on object creation, memory usage, and performance through clear code examples.

Python Crawling & Data Mining
Python Crawling & Data Mining
Python Crawling & Data Mining
Unlocking Python’s __new__: Build Singletons, Multitons, and Cache Efficiently

Introduction

Python’s special methods surrounded by double underscores let developers customize class behavior. This article focuses on the constructor method __new__, its role in object creation, and how to override it to implement singleton, multiton, and caching patterns.

1. What is __new__ ?

__new__

is called before __init__. It creates the instance (allocates memory) and returns it; __init__ then initializes the object. It is a static method of the class.

class Solution(object):
    def __init__(self, name=None, data=None):
        self.name = name
        self.data = data
        self.xml_load(self.data)

    def xml_load(self, data):
        print("初始化init", data)

    def Parser(self):
        print("解析完成finish", self.name)

a = Solution(name="A111", data=10)
a.Parser()
b = Solution(name="A112", data=20)
b.Parser()
print(a)
print(b)
print(id(a))
print(id(b))

When a class does not define __new__, Python uses the parent class’s implementation, which simply allocates space for the new object.

2. Overriding __new__ for a Singleton

By storing a single instance in a class attribute and always returning it from __new__, the class guarantees only one object exists.

class Solution:
    _instance = None

    def __init__(self, name, data):
        self.name = name
        self.data = data
        self.xml_load(self.data)

    def __new__(cls, *args, **kwargs):
        if cls._instance is None:
            cls._instance = super().__new__(cls)
            return cls._instance
        return cls._instance

    def xml_load(self, data):
        print("初始化init", self.name, data)

    def Parser(self):
        print("解析完成finish", self.name)

a = Solution("A11", 10)
a.Parser()
b = Solution("A12", 20)
b.Parser()
print(id(a))
print(id(b))
print(a.name)
print(b.name)

If __new__ does not return the created instance, the subsequent __init__ call fails with an AttributeError.

3. Multiton (cached factory) with __new__

Using a dictionary to store instances keyed by a parameter (e.g., name) allows multiple singletons – one per key – and avoids repeated initialization.

class Solution:
    _loaded = {}

    def __init__(self, name, data):
        self.name = name
        self.data = data
        self.xml_load(self.data)

    def __new__(cls, name, *args, **kwargs):
        if name in cls._loaded:
            print(f"已经存在访问对象 {name}")
            return cls._loaded[name]
        print(f"正在创建访问对象 {name}")
        instance = super().__new__(cls)
        cls._loaded[name] = instance
        return instance

    def xml_load(self, data):
        print("初始化init", self.name, data)

    def Parser(self):
        print("解析完成finish", self.name)

a = Solution("A11", 10)
a.Parser()
b = Solution("A11", 10)
b.Parser()
c = Solution("A12", 20)
c.Parser()
print(a is b)

This pattern keeps each distinct key’s object in memory, so subsequent requests reuse the same instance and skip costly initialization steps such as database connections or file reads.

Summary

__new__

is invoked before __init__ to allocate memory for a new object.

The method must return the created instance; otherwise object creation fails.

A singleton can be implemented by storing a single instance in a class attribute and returning it from __new__.

Multiton or cached factories keep a dictionary of created objects and reuse them based on a key, providing per‑key singletons.

These patterns reduce redundant resource allocation, improve performance, and simplify management of shared resources.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

PythoncachingObject Creationdesign patternSingletonnewmultiton
Python Crawling & Data Mining
Written by

Python Crawling & Data Mining

Life's short, I code in Python. This channel shares Python web crawling, data mining, analysis, processing, visualization, automated testing, DevOps, big data, AI, cloud computing, machine learning tools, resources, news, technical articles, tutorial videos and learning materials. Join us!

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.