Intermediate Python 📂 Class and Object · 9 of 10 226 min read

Python OOP — new, call, and the Singleton Pattern Explained

Master three tightly-linked advanced OOP topics: new (the constructor that runs before init), call (makes instances callable like functions), and the Singleton pattern (ensures only one instance ever exists). Learn through a two-step-birth analogy, three animated SVG diagrams (creation lifecycle, callable dispatch, singleton reuse), Config-Singleton and callable Counter/Validator examples, plus 10 golden rules.

🌐
SectionSection第 01 节

The Story That Explains These Three Ideas 🚗इन तीन विचारों को समझाने वाली कहानी 🚗一个讲清这三个概念的故事 🚗

The Two-Step Birth of an ObjectObject का दो-क़दम वाला जन्म对象的两步诞生
Think about how a car is made. It is always two steps:

Step 1 — build the body. The factory line rolls out a steel body. It is a real car now, but empty inside. That is __new__ — it creates the object.

Step 2 — fit it out. Painters add colour, workers fit the seats and dashboard. That is __init__ — it fills in the freshly created object.

So every time you write Car("Honda"), Python runs __new__ to build the empty car, then __init__ to fill in "Honda" as the brand.

Two twists follow. First: some things exist only once — the Sun, the company CEO, the app settings. Ask for one a hundred times and you get the same one every time. That is the Singleton pattern — you customise __new__ to always hand back the same object. Second: some objects act like verbs — you press them and they do something. A horn is an object, but horn() makes a sound. That is __call__ — it lets you call the object itself, just like a function.
सोचिए कार कैसे बनती है। यह हमेशा दो क़दम में होता है:

क़दम 1 — ढाँचा बनाओ। Factory line से steel का ढाँचा निकलता है। अब यह असली कार है, पर अंदर से ख़ाली। यही __new__ है — यह object बनाता है।

क़दम 2 — सजाओ। Painters रंग करते हैं, कारीगर seats और dashboard लगाते हैं। यही __init__ है — यह अभी बने object को भरता है।

तो जब भी आप Car("Honda") लिखते हैं, Python पहले __new__ से ख़ाली कार बनाता है, फिर __init__ से brand में "Honda" भरता है।

आगे दो मोड़ हैं। पहला: कुछ चीज़ें एक ही होती हैं — सूरज, company का CEO, app की settings। सौ बार माँगिए, हर बार वही एक मिलेगी। यही Singleton pattern है — आप __new__ को ऐसा बनाते हैं कि वह हमेशा वही object लौटाए। दूसरा: कुछ objects क्रिया जैसे होते हैं — दबाओ तो वे कुछ करते हैं। Horn एक object है, पर horn() आवाज़ करता है। यही __call__ है — इससे आप object को ही function की तरह बुला सकते हैं।
想想汽车是怎么造出来的。它总是分 两步:

第 1 步 — 造车身。 生产线推出一个钢制车身。它已经是一辆真正的车了,但里面是空的。这就是 __new__ — 它 创建 对象。

第 2 步 — 装配。 油漆工上色,工人安装座椅和仪表盘。这就是 __init__ — 它 填充 刚创建的对象。

所以每次你写 Car("Honda"),Python 先运行 __new__ 造出空车,再运行 __init__ 把品牌填为 "Honda"。

接下来有两个变化。第一:有些东西只有一个 — 太阳、公司 CEO、应用设置。要一百次,每次得到的都是同一个。这就是 单例模式(Singleton) — 你定制 __new__,让它总是返回同一个对象。第二:有些对象像动词 — 按一下就会 做 某事。喇叭是一个对象,但 horn() 会发出声音。这就是 __call__ — 它让你像调用函数一样调用对象本身。
🔮
The Core Insightमूल बात核心要点

__new__ creates the object. __init__ fills it in. __call__ lets the object be called like a function. Combine them and you get singletons (one object, always reused) and callable objects (verbs in class form). Three tools, one connected family.

__new__ object बनाता है। __init__ उसे भरता है। __call__ object को function की तरह बुलाने देता है। इन्हें मिलाइए और मिलते हैं singletons (एक ही object, हमेशा दोबारा इस्तेमाल) और callable objects (class के रूप में क्रियाएँ)। तीन औज़ार, एक जुड़ा हुआ परिवार।

__new__ 创建对象,__init__ 填充对象,__call__ 让对象可以像函数一样被调用。把它们组合起来,就得到 单例(只有一个对象,始终复用)和 可调用对象(以类的形式表达的动词)。三个工具,一个相互关联的家族。

▶️
This Tutorial Has Four Simulators and a Quizइस Tutorial में चार Simulators और एक Quiz है本教程有四个模拟器和一个小测验

Look for the interactive boxes: Object Birth, Step by Step (Section 02), the Callable Workshop (04), the Singleton Lab (07) and the Bug Doctor (11). Every result comes from real Python runs.

Interactive डिब्बे खोजें: Object का जन्म, क़दम-दर-क़दम (Section 02), Callable Workshop (04), Singleton Lab (07) और Bug Doctor (11)। हर नतीजा असली Python runs से है।

请留意这些互动框:对象的诞生 · 逐步演示(第 02 节)、可调用对象工坊(04)、单例实验室(07)和 Bug 医生(11)。每个结果都来自真实的 Python 运行。


SectionSection第 02 节

__new__ vs __init__ — The Full Lifecycle 🏗️__new__ बनाम __init__ — पूरा Lifecycle 🏗️__new__ vs __init__ — 完整的生命周期 🏗️

When you write Person("Alice", 30), two methods run in order. Almost every class only needs __init__ — Python's default __new__ does the creation quietly. Knowing both is what lets you build singletons and subclasses of immutable built-in types (and, later, metaclasses — an upcoming tutorial).

जब आप Person("Alice", 30) लिखते हैं, तो दो methods क्रम से चलते हैं। लगभग हर class को सिर्फ़ __init__ चाहिए — Python का default __new__ चुपचाप object बना देता है। दोनों को समझकर ही आप singletons और immutable built-in types की subclasses बना पाते हैं (और आगे metaclasses भी — आने वाले tutorial में)।

当你写 Person("Alice", 30) 时,两个方法会依次运行。几乎所有类都只需要 __init__ — Python 默认的 __new__ 会悄悄完成创建。理解这两者,才能写出单例和不可变内置类型的子类(以及之后的元类 — 后续教程)。

🏗️ What Actually Happens on Person("Alice", 30)Person("Alice", 30) पर असल में क्या होता है执行 Person("Alice", 30) 时实际发生了什么
Step 1क़दम 1第 1 步
Python calls Person.__new__(cls, "Alice", 30). It creates a bare, empty Person object and returns it.
Python Person.__new__(cls, "Alice", 30) बुलाता है। यह एक ख़ाली Person object बनाता है और उसे लौटाता है।
Python 调用 Person.__new__(cls, "Alice", 30)。它 创建 一个空的 Person 对象并 返回 它。
Step 2क़दम 2第 2 步
If that result is a Person, Python calls Person.__init__(new_object, "Alice", 30). It fills in the attributes on that object.
अगर वह नतीजा Person है, तो Python Person.__init__(new_object, "Alice", 30) बुलाता है। यह उस object पर attributes भरता है।
如果结果是一个 Person,Python 接着调用 Person.__init__(new_object, "Alice", 30),它在该对象上 填充 属性。
Step 3क़दम 3第 3 步
The finished object is what your variable now points to.
तैयार object वह है जिसकी ओर आपका variable अब इशारा करता है।
你的变量现在指向这个已完成的对象。
Ruleनियम规则
__new__ receives the class (cls) — there is no object yet, so no self. __init__ receives the object (self) that __new__ just made.
__new__ को class (cls) मिलती है — अभी object नहीं है, इसलिए self नहीं। __init__ को वह object (self) मिलता है जो __new__ ने अभी बनाया।
__new__ 接收的是 类(cls)— 此时还没有对象,所以没有 self。__init__ 接收的是 __new__ 刚创建的 对象(self)。
class Person:
    def __new__(cls, *args, **kwargs):
        print(f"  [__new__] creating a new Person object")
        instance = super().__new__(cls)      # let object create it for us
        return instance                      # MUST return the new object

    def __init__(self, name, age):
        print(f"  [__init__] filling in name={name!r}, age={age}")
        self.name = name
        self.age  = age

print("Creating Alice:")
alice = Person("Alice", 30)
print()
print("Creating Bob:")
bob = Person("Bob", 25)
OUTPUT
Creating Alice: [__new__] creating a new Person object [__init__] filling in name='Alice', age=30 Creating Bob: [__new__] creating a new Person object [__init__] filling in name='Bob', age=25
The Two-Step Object Creationदो क़दम में Object बनना两步创建对象
new then init lifecyclePerson("Alice", 30)STEP 1 · __new__(cls, …)क़दम 1 · __new__(cls, …)第 1 步 · __new__(cls, …)creates and returns a bare objectख़ाली object बनाता और लौटाता है创建并返回一个空对象Person #1 { }is it a Person? yes → call __init__क्या यह Person है? हाँ → __init__ बुलाओ是 Person 吗?是 → 调用 __init__STEP 2 · __init__(self, name, age)क़दम 2 · __init__(self, name, age)第 2 步 · __init__(self, name, age)fills in the object __new__ just built__new__ के बनाए object को भरता है填充 __new__ 刚创建的对象Person #1 {name: 'Alice', age: 30}→ your variable points to this finished object→ आपका variable इस तैयार object की ओर इशारा करता है→ 你的变量指向这个完成的对象

Every Person(...) call runs this two-step pipeline: __new__ builds the empty shell; __init__ fills it in.

हर Person(...) call यही दो क़दम चलाती है: __new__ ख़ाली ढाँचा बनाता है; __init__ उसे भरता है।

每次调用 Person(...) 都会走这两步:__new__ 造出空壳,__init__ 把它填好。

👣 Simulator: Object Birth, Step by Step👣 Simulator: Object का जन्म, क़दम-दर-क़दम👣 模拟器:对象的诞生 · 逐步演示

Recorded with sys.settrace. Watch the call stack: first __new__ (with cls, no self), then __init__ (with self). Then try the two broken versions — when __new__ does not return a Person, __init__ never runs.

sys.settrace से रिकॉर्ड किया हुआ। Call stack देखिए: पहले __new__ (cls के साथ, self नहीं), फिर __init__ (self के साथ)। फिर दोनों टूटे versions आज़माइए — जब __new__ Person नहीं लौटाता, तो __init__ कभी नहीं चलता।

用 sys.settrace 录制。观察调用栈:先是 __new__(有 cls,没有 self),然后是 __init__(有 self)。再试试两个有问题的版本 — 当 __new__ 没有返回 Person 时,__init__ 根本不会运行。

Object Birth, Step by StepObject का जन्म, क़दम-दर-क़दम对象的诞生 · 逐步演示recorded with sys.settracesys.settrace से रिकॉर्ड用 sys.settrace 录制
__new__ ends with:__new__ का अंत:__new__ 的结尾:
CodeCode代码
Call stack (newest at the bottom)Call stack (सबसे नया नीचे)调用栈(最新的在最下面)
The objectObject对象
OutputOutput输出

SectionSection第 03 节

When Do You Actually Override __new__? 🤔__new__ को असल में कब override करें? 🤔什么时候才需要重写 __new__?🤔

Almost no Python class touches __new__ — the default handles it. You reach for it only when you need to control which object comes back, or when you subclass an immutable built-in type.

लगभग कोई Python class __new__ को नहीं छूती — default काम कर देता है। इसकी ज़रूरत तभी पड़ती है जब आपको तय करना हो कि कौन-सा object लौटे, या जब आप किसी immutable built-in type की subclass बनाएँ।

几乎没有 Python 类会去碰 __new__ — 默认实现就够了。只有当你需要控制返回 哪个 对象,或者要继承不可变的内置类型时,才会用到它。

🔄
Singleton PatternSingleton Pattern单例模式
reuse the same instanceवही instance दोबारा复用同一个实例
Check if an instance already exists. If yes, return it; if not, create one. This is the most common real-world use of __new__.
जाँचिए कि instance पहले से है या नहीं। है तो वही लौटाइए; नहीं तो बनाइए। __new__ का सबसे आम असली इस्तेमाल यही है।
检查实例是否已存在:存在就返回它,不存在就创建一个。这是 __new__ 在实际中最常见的用法。
🔐
Immutable SubclassesImmutable Subclasses不可变类型的子类
extend str, int, tuplestr, int, tuple बढ़ाना扩展 str、int、tuple
When you subclass str, int or tuple, the value is already fixed by the time __init__ runs. To change the value itself, do it in __new__. (A full example comes in an upcoming tutorial.)
str, int या tuple की subclass में, __init__ चलने तक value पहले ही तय हो चुकी होती है। Value ख़ुद बदलनी हो तो यह __new__ में करें। (पूरा उदाहरण आने वाले tutorial में।)
继承 str、int 或 tuple 时,__init__ 运行之前 值 就已经固定了。要改变值本身,就在 __new__ 中处理。(完整示例见后续教程。)
🏭
Object Pool / CacheObject Pool / Cache对象池 / 缓存
reuse frequent instancesबार-बार वाले instances दोबारा复用常用实例
Return an existing object from a pool when the same key is asked for again. CPython does something similar for small integers (−5 to 256): they are created once and reused.
वही key दोबारा माँगी जाए तो pool से मौजूदा object लौटाइए। CPython छोटे integers (−5 से 256) के साथ कुछ ऐसा ही करता है: वे एक बार बनते हैं और दोबारा इस्तेमाल होते हैं।
当同一个键再次被请求时,从池中返回已有对象。CPython 对小整数(−5 到 256)也做了类似的事:它们只创建一次,之后反复复用。
⚠️
Two Rules to Rememberयाद रखने के दो नियम两条要记住的规则

__new__ is a static method (Python makes it one automatically) whose first argument is cls — the class, not self. It must return an object. If it returns something that is not an instance of cls, Python skips __init__. Try that in the simulator above.

__new__ एक static method है (Python इसे अपने आप ऐसा बनाता है) जिसका पहला argument cls है — class, self नहीं। इसे object लौटाना ही होगा। अगर यह ऐसा कुछ लौटाए जो cls का instance नहीं है, तो Python __init__ छोड़ देता है। ऊपर के simulator में यह आज़माइए।

__new__ 是一个静态方法(Python 会自动把它变成静态方法),第一个参数是 cls — 类,不是 self。它 必须返回一个对象。如果返回的不是 cls 的实例,Python 就会 跳过 __init__。在上面的模拟器里试试看。


SectionSection第 04 节

__call__ — Making an Instance Callable 📞__call__ — Instance को Callable बनाना 📞__call__ — 让实例可以被调用 📞

Functions are callable — len(), print(), your own calculate(). Objects usually are not. Defining __call__ changes that: now you can call your object with (), just like a function.

Functions callable होते हैं — len(), print(), आपका अपना calculate()। Objects आमतौर पर नहीं होते। __call__ define करने से यह बदल जाता है: अब आप अपने object को () से बुला सकते हैं, ठीक function की तरह।

函数是可调用的 — len()、print()、你自己的 calculate()。对象通常 不是。定义 __call__ 就改变了这一点:现在你可以像调用函数一样用 () 调用你的对象。

class Multiplier:
    def __init__(self, factor):
        self.factor = factor

    # -- This makes the instance callable --
    def __call__(self, x):
        return x * self.factor


double = Multiplier(2)
triple = Multiplier(3)

# Instances now behave like functions
print(double(10))    # 20   <- calls double.__call__(10)
print(triple(10))    # 30   <- calls triple.__call__(10)

# They can even be passed anywhere a function is expected
print(list(map(double, [1, 2, 3])))   # [2, 4, 6]

# They remain OBJECTS - you can inspect and change state
print(double.factor)          # 2
double.factor = 5
print(double(10))            # 50   <- same instance, new behaviour
OUTPUT
20 30 [2, 4, 6] 2 50
obj(x) Becomes obj.__call__(x)obj(x) बनता है obj.__call__(x)obj(x) 变成 obj.__call__(x)
call dispatchWHAT YOU WRITEजो आप लिखते हैं你写的double(10)Python translatesPython बदलता हैPython 翻译WHAT PYTHON RUNSजो PYTHON चलाता हैPython 实际运行的double.__call__(10)YOUR __call__ RUNSआपका __call__ चलता है你的 __call__ 运行def __call__(self, x): return x * self.factor # 10 * 2RESULTनतीजा结果20

Calling an object with () is really Python calling its __call__ method. Same syntax as a function, but the object keeps its state.

() से object बुलाना असल में Python का उसका __call__ method बुलाना है। Function जैसा syntax, पर object अपनी state रखता है।

用 () 调用对象,其实就是 Python 调用它的 __call__ 方法。语法和函数一样,但对象保留着自己的状态。

🛠️ Simulator: Callable Workshop🛠️ Simulator: Callable Workshop🛠️ 模拟器:可调用对象工坊

Pick one of the three callable classes from this tutorial and press the buttons to run lines. Watch obj(…) turn into obj.__call__(…), and watch the object's own state change between calls. Checked against Python on 300 random sequences.

इस tutorial की तीन callable classes में से एक चुनिए और lines चलाने के लिए buttons दबाइए। देखिए obj(…) कैसे obj.__call__(…) बनता है, और calls के बीच object की अपनी state कैसे बदलती है। 300 random sequences पर Python से जाँचा गया।

从本教程的三个可调用类中选一个,按按钮运行代码。观察 obj(…) 如何变成 obj.__call__(…),以及对象自身的状态在多次调用之间如何变化。已在 300 个随机序列上与 Python 对照。

Callable WorkshopCallable Workshop可调用对象工坊300 sequences checked300 sequences जाँचे已核对 300 个序列
Object:Object:对象:
Run:चलाएँ:运行:
The classClass类
Lines you ranचलाई गई lines你运行的代码
The object — state kept between callsObject — calls के बीच रखी state对象 — 调用之间保留的状态
OutputOutput输出

SectionSection第 05 节

Why Callable Classes Instead of Just Functions? 🤷सिर्फ़ Functions की जगह Callable Classes क्यों? 🤷为什么用可调用类而不只用函数?🤷

🛠️ Plain Functionसादा Function普通函数
No memory between callsCalls के बीच कोई याद नहीं调用之间没有记忆
Settings passed in every timeहर बार settings देनी पड़ती हैं每次都要传入配置
Fine for work with no stateबिना state वाले काम के लिए ठीक适合无状态的操作
def multiply(x, factor):def multiply(x, factor):def multiply(x, factor):
🔥 Callable InstanceCallable Instance可调用实例
Carries state across callsCalls के बीच state रखता है在调用之间保留状态
Set up once, when it is createdबनते समय एक बार set up创建时配置一次
Reads like a function, behaves like an objectFunction जैसा पढ़ा जाता है, object जैसा चलता है读起来像函数,用起来像对象
Multiplier(2) — then reuse it foreverMultiplier(2) — फिर हमेशा दोबारा इस्तेमालMultiplier(2) — 之后一直复用

Common patterns that benefit from __call__:

__call__ से फ़ायदा पाने वाले आम patterns:

受益于 __call__ 的常见模式:

PatternPattern模式Ideaविचार思路
Configured functionsConfigured functions预先配置的函数A validator with rules set when it is created (MinLengthValidator(8)), then called as validator("input") — see Section 10बनते समय नियम तय करने वाला validator (MinLengthValidator(8)), फिर validator("input") से बुलाया जाता है — Section 10 देखें创建时就设定规则的校验器(MinLengthValidator(8)),之后以 validator("input") 调用 — 见第 10 节
Counters and accumulatorsCounters और accumulators计数器与累加器The object carries the running total between calls — see Section 09Object calls के बीच कुल योग रखता है — Section 09 देखें对象在调用之间保存累计值 — 见第 09 节
Decorators as classesClasses के रूप में decorators类形式的装饰器@Retry(max_attempts=3) — the decorator's __call__ wraps the function (upcoming tutorial)@Retry(max_attempts=3) — decorator का __call__ function को लपेटता है (आने वाला tutorial)@Retry(max_attempts=3) — 装饰器的 __call__ 包装函数(后续教程)
Pipelines / transformsPipelines / transforms流水线 / 转换Pipeline(steps), then pipeline(data)Pipeline(steps), फिर pipeline(data)Pipeline(steps),然后 pipeline(data)
Fluent APIsFluent APIs流式 APIChainable calls that also keep state you can inspectजुड़ने वाली calls जो जाँचने लायक state भी रखती हैं可链式调用,同时保留可检查的状态

SectionSection第 06 节

The Singleton Pattern — One Instance, Reused Forever ☀️Singleton Pattern — एक Instance, हमेशा दोबारा ☀️单例模式 — 只有一个实例,永远复用 ☀️

A singleton is a class that only ever produces one object. However many times you call Config(), you get the same Config object. It suits app-wide things — settings, database connections, logging, caches.

Singleton ऐसी class है जो हमेशा एक ही object बनाती है। Config() कितनी भी बार बुलाइए, वही Config object मिलता है। यह पूरे app की चीज़ों के लिए ठीक है — settings, database connections, logging, caches।

单例 是只会产生 一个对象 的类。无论调用 Config() 多少次,得到的都是 同一个 Config 对象。它适合全应用共享的东西 — 配置、数据库连接、日志、缓存。

class Config:
    _instance = None                       # class variable - the "one and only" slot

    def __new__(cls, *args, **kwargs):
        if cls._instance is None:
            print("  [__new__] first call — creating THE instance")
            cls._instance = super().__new__(cls)
        else:
            print("  [__new__] already exists — returning the same instance")
        return cls._instance

    def __init__(self, filename=None):
        # NOTE: __init__ runs on EVERY Config(...) call - beware of overwriting
        if filename is not None:
            self.filename = filename


print("First call:")
a = Config("app.ini")

print("\nSecond call:")
b = Config()

print("\nThird call:")
c = Config("override.ini")

print()
print("a is b:", a is b)           # True - literally the same object
print("b is c:", b is c)           # True
print("a.filename:", a.filename)   # override.ini (the last __init__ overwrote it)
OUTPUT
First call: [__new__] first call — creating THE instance Second call: [__new__] already exists — returning the same instance Third call: [__new__] already exists — returning the same instance a is b: True b is c: True a.filename: override.ini
🔥
The __init__ Gotcha__init__ वाली चूक__init__ 的陷阱

__init__ runs on every Config(...) call — even when __new__ returned the existing object. So calling Config("override.ini") later overwrites the filename set the first time. Guard against this if you don't want it (Section 07 shows the "initialised flag" pattern).

__init__ हर Config(...) call पर चलता है — तब भी जब __new__ ने मौजूदा object लौटाया। इसलिए बाद में Config("override.ini") बुलाने पर पहली बार वाला filename बदल जाता है। अगर यह नहीं चाहिए तो इससे बचाव कीजिए (Section 07 में "initialised flag" pattern है)।

__init__ 在 每一次 Config(...) 调用时都会运行 — 即使 __new__ 返回的是已有对象。所以之后再调用 Config("override.ini") 会 覆盖 第一次设置的文件名。如果不希望这样,就要加以防护(第 07 节介绍"已初始化标志"模式)。

All Three Calls Return the Same Objectतीनों Calls एक ही Object लौटाती हैं三次调用都返回同一个对象
Singleton returns the same instanceCALL 1CALL 1第 1 次调用a = Config("app.ini")CALL 2CALL 2第 2 次调用b = Config()CALL 3CALL 3第 3 次调用c = Config("override.ini")THE ONE INSTANCEएकमात्र INSTANCE唯一的实例Config._instanceevery call returnsहर call यही每次调用都返回this same objectobject लौटाती है这同一个对象filename = 'override.ini'(the last __init__ wins)(आख़िरी __init__ जीतता है)(最后一次 __init__ 生效)a is b is c → Truenot three objects — one object, three namesतीन objects नहीं — एक object, तीन नाम不是三个对象 — 一个对象,三个名字

Three calls, one object. __new__ checks the slot and hands back the existing object; __init__ still runs each time.

तीन calls, एक object। __new__ slot जाँचकर मौजूदा object लौटाता है; __init__ फिर भी हर बार चलता है।

三次调用,一个对象。__new__ 检查槽位并返回已有对象;__init__ 仍然每次都运行。


SectionSection第 07 节

A Safer Singleton — Guard __init__ Too 🛡️सुरक्षित Singleton — __init__ को भी बचाएँ 🛡️更安全的单例 — 也要保护 __init__ 🛡️

Because __init__ runs on every construction call, you often want a flag so the real setup runs only once. This "initialised once" pattern is used in most real singletons.

क्योंकि __init__ हर बार object बनाने की call पर चलता है, अक्सर एक flag चाहिए ताकि असली setup सिर्फ़ एक बार चले। ज़्यादातर असली singletons में यही "एक बार initialise" pattern होता है।

由于 __init__ 在每次构造调用时都会运行,通常需要一个标志,让真正的初始化只执行一次。大多数真实的单例都使用这种"只初始化一次"的模式。

class ConfigManager:
    _instance = None
    _initialized = False

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

    def __init__(self, filename="app.ini"):
        # Guard: don't re-run on later construction calls
        if ConfigManager._initialized:
            return
        print(f"Loading {filename} — this runs ONCE")
        self.filename = filename
        self.settings = {"debug": True, "version": "2.4"}
        ConfigManager._initialized = True


a = ConfigManager("app.ini")             # prints "Loading app.ini..."
b = ConfigManager("different.ini")       # silent - already initialised

print(a.filename)                        # app.ini (still the first value)
print(a is b)                            # True
OUTPUT
Loading app.ini — this runs ONCE app.ini True

☀️ Simulator: Singleton Lab☀️ Simulator: Singleton Lab☀️ 模拟器:单例实验室

Press the call buttons to create up to six names. Compare three versions of Config: a normal class, the plain singleton from Section 06, and the guarded one from this section. Watch where each name points and what filename ends up as. Checked against Python on 300 random sequences.

Call buttons दबाकर छह तक नाम बनाइए। Config के तीन versions की तुलना कीजिए: सामान्य class, Section 06 वाला सादा singleton, और इस section वाला guarded singleton। देखिए हर नाम कहाँ इशारा करता है और filename आख़िर में क्या बनता है। 300 random sequences पर Python से जाँचा गया।

按调用按钮,最多创建六个名字。比较 Config 的三个版本:普通类、第 06 节的简单单例,以及本节带防护的单例。观察每个名字指向哪里,以及 filename 最终是什么。已在 300 个随机序列上与 Python 对照。

Singleton LabSingleton Lab单例实验室300 sequences checked300 sequences जाँचे已核对 300 个序列
Version:Version:版本:
Call:Call:调用:
The classClass类
The programProgram程序
Names → objectsनाम → objects名字 → 对象
OutputOutput输出

SectionSection第 08 节

Alternative Singleton Patterns 🔀Singleton के दूसरे Patterns 🔀其他单例写法 🔀

The __new__ approach is the most direct, but Python offers other ways to get the same effect. Each suits a different style.

__new__ वाला तरीक़ा सबसे सीधा है, पर Python यही असर पाने के दूसरे तरीक़े भी देता है। हर एक अलग style के लिए ठीक है।

__new__ 的方式最直接,但 Python 还提供了其他方式来达到同样的效果,各自适合不同的风格。

Pattern 1 — DecoratorPattern 1 — Decorator写法 1 — 装饰器

def singleton(cls):
    instances = {}
    def get_instance(*args, **kwargs):
        if cls not in instances:
            instances[cls] = cls(*args, **kwargs)
        return instances[cls]
    return get_instance


@singleton
class Database:
    def __init__(self, host):
        self.host = host

db1 = Database("localhost")
db2 = Database("other-host")
print(db1 is db2)   # True
print(db1.host)     # localhost (the second call was ignored)
print(Database)     # the name now points to the wrapper function, not the class
OUTPUT
True localhost <function singleton.<locals>.get_instance at 0x7f…>
🔎
Look at the Last Lineआख़िरी Line देखिए看最后一行

After @singleton, the name Database points to the inner get_instance function, not to the class. That is why isinstance(db1, Database) fails with TypeError (see the Bug Doctor in Section 11). The __new__ version keeps Database a real class.

@singleton के बाद नाम Database अंदर वाले get_instance function की ओर इशारा करता है, class की ओर नहीं। इसीलिए isinstance(db1, Database) TypeError देता है (Section 11 का Bug Doctor देखें)। __new__ वाला version Database को असली class बनाए रखता है।

加上 @singleton 之后,名字 Database 指向内部的 get_instance 函数,而不是类。这就是为什么 isinstance(db1, Database) 会抛出 TypeError(见第 11 节的 Bug 医生)。__new__ 版本则让 Database 保持为真正的类。

Pattern 2 — Module-Level (the Pythonic Default)Pattern 2 — Module-Level (Pythonic default)写法 2 — 模块级(Python 风格的默认做法)

# In config.py - the module itself IS the singleton
settings = {"debug": True, "version": "2.4"}

def get(key):
    return settings.get(key)

# Anywhere else:
# from config import settings, get
# Every import gets the same module -> the same settings dict - a natural singleton
💡
The Pythonic TruthPythonic सचPython 风格的真相

In many real Python projects, the "singleton" is just a module. Python runs a module once and caches it, so import config in ten different files gives every file the same config object. No __new__, no decorator — just a plain module. Use a __new__-based singleton only when you really need class features (subclassing, methods with behaviour).

कई असली Python projects में "singleton" बस एक module होता है। Python module को एक बार चलाकर cache कर लेता है, इसलिए दस अलग files में import config करने पर हर file को वही config object मिलता है। न __new__, न decorator — बस एक सादा module। __new__ वाला singleton तभी लें जब सच में class की सुविधाएँ चाहिए (subclassing, व्यवहार वाले methods)।

在很多真实的 Python 项目中,"单例"就是一个 模块。Python 只运行一次模块并缓存它,所以在十个不同文件中 import config,每个文件得到的都是同一个 config 对象。不需要 __new__,不需要装饰器 — 只是一个普通模块。只有在确实需要类的特性(子类化、带行为的方法)时,才使用基于 __new__ 的单例。


SectionSection第 09 节

Practical Example — A Callable Counter With State 🔢Practical Example — State वाला Callable Counter 🔢实战示例 — 带状态的可调用计数器 🔢

A class that acts like a function but remembers how many times it has been called. A classic __call__ use. Try it in the Callable Workshop (Section 04) with Counter().

ऐसी class जो function की तरह चलती है पर याद रखती है कि उसे कितनी बार बुलाया गया। __call__ का क्लासिक इस्तेमाल। Callable Workshop (Section 04) में Counter() से आज़माइए।

一个像函数一样工作、却能记住自己被调用了多少次的类。这是 __call__ 的经典用法。到可调用对象工坊(第 04 节)选 Counter() 试试。

class Counter:
    def __init__(self, start=0):
        self.count = start

    def __call__(self):
        self.count += 1
        return self.count

    def reset(self):
        self.count = 0

    def __repr__(self):
        return f"Counter(count={self.count})"


c = Counter()
print(c())     # 1  <- called like a function
print(c())     # 2
print(c())     # 3

# Still an object - you can inspect and reset
print(c)       # Counter(count=3)
c.reset()
print(c())     # 1 (started over)

# Several independent counters - each carries its own state
hits    = Counter()
misses  = Counter()
hits(); hits(); hits()
misses()
print(f"hits={hits.count}, misses={misses.count}")   # hits=3, misses=1
OUTPUT
1 2 3 Counter(count=3) 1 hits=3, misses=1

SectionSection第 10 节

Practical Example — A Callable Validator ✅Practical Example — Callable Validator ✅实战示例 — 可调用的校验器 ✅

Combine __call__ with settings stored in __init__ to build small, reusable validation objects. Set up once, call anywhere.

__call__ को __init__ में रखी settings के साथ मिलाकर छोटे, दोबारा इस्तेमाल होने वाले validation objects बनाइए। एक बार set up, कहीं भी call।

把 __call__ 和 __init__ 中保存的配置结合起来,构建小巧、可复用的校验对象。配置一次,随处调用。

class MinLengthValidator:
    def __init__(self, min_length):
        self.min_length = min_length

    def __call__(self, value):
        # Uses the setting from __init__ every time it is called
        if len(value) < self.min_length:
            raise ValueError(
                f"{value!r} must be at least {self.min_length} chars"
            )
        return value


# Build once, use everywhere
username_valid = MinLengthValidator(3)
password_valid = MinLengthValidator(8)

# Call the instances like functions
print(username_valid("alice"))       # alice
print(password_valid("SecureP@ss"))  # SecureP@ss

try:
    password_valid("abc")
except ValueError as e:
    print("Blocked:", e)

# A callable object can be passed to higher-order functions like map()
inputs = ["alice", "bob", "chandra"]
valid_names = list(map(username_valid, inputs))
print(valid_names)
OUTPUT
alice SecureP@ss Blocked: 'abc' must be at least 8 chars ['alice', 'bob', 'chandra']
🔧
Fixed: The Last Lines Now Really Pass the Callableसुधार: आख़िरी Lines अब सच में Callable देती हैं已修正:最后几行现在真正传入了可调用对象

The original comment said "callables can be passed to higher-order functions", but the code then checked len(n) >= username_valid.min_length by hand and never passed the object anywhere. Now it does: map(username_valid, inputs) calls the object once per name. The comments on the first two prints are also fixed — print() shows alice, not 'alice'.

मूल comment में लिखा था "callables को higher-order functions में दे सकते हैं", पर code ने फिर len(n) >= username_valid.min_length हाथ से जाँचा और object कहीं दिया ही नहीं। अब देता है: map(username_valid, inputs) हर नाम के लिए object को एक बार बुलाता है। पहले दो prints के comments भी ठीक किए — print() alice दिखाता है, 'alice' नहीं।

原注释说"可调用对象可以传给高阶函数",但代码随后却手动检查 len(n) >= username_valid.min_length,根本没有把对象传给任何函数。现在改为:map(username_valid, inputs) 对每个名字调用一次该对象。前两个 print 的注释也已修正 — print() 显示 alice,而不是 'alice'。


SectionSection第 11 节

Common Mistakes (and Fixes) 🩹आम ग़लतियाँ (और उनके हल) 🩹常见错误(及修正)🩹

Mistakeग़लती错误What goes wrongक्या बिगड़ता है会出什么问题Fixहल修正
Forgetting to return from __new____new__ से return भूलना忘记在 __new__ 中 returnPerson(...) gives None, and __init__ never runsPerson(...) None देता है, और __init__ कभी नहीं चलताPerson(...) 得到 None,而且 __init__ 从不运行Always end __new__ with return instance (or return cls._instance)__new__ को हमेशा return instance (या return cls._instance) से ख़त्म करें__new__ 末尾始终写 return instance(或 return cls._instance)
Naming the first parameter of __new__ self__new__ के पहले parameter का नाम self रखना把 __new__ 的第一个参数命名为 selfIt still runs (a name is just a name), but it misleads readers — that argument is the class, because no object exists yetयह फिर भी चलता है (नाम बस नाम है), पर पढ़ने वालों को भटकाता है — वह argument class है, क्योंकि अभी object है ही नहीं代码照样能运行(名字只是名字),但会误导读者 — 那个参数是 类,因为对象还不存在Write def __new__(cls, ...):def __new__(cls, ...): लिखें写成 def __new__(cls, ...):
Setting attributes in __new__ that __init__ overwrites__new__ में ऐसे attributes रखना जिन्हें __init__ बदल देता है在 __new__ 中设置会被 __init__ 覆盖的属性Whatever __new__ sets is replaced by __init__ right after__new__ जो रखता है, __init__ तुरंत बाद बदल देता है__new__ 设置的值紧接着就被 __init__ 替换Set state in __init__. Use __new__ only for creation and identityState __init__ में रखें। __new__ सिर्फ़ बनाने और पहचान के लिए状态放在 __init__ 中。__new__ 只负责创建和身份
Singleton with changing state, no re-init guardबदलने वाली state वाला singleton, re-init guard नहीं有可变状态的单例,却没有重复初始化防护A later call's __init__ quietly overwrites the first call's settingsबाद की call का __init__ पहली call की settings चुपचाप बदल देता है之后调用的 __init__ 会悄悄覆盖第一次的配置Add an _initialized flag and return early from __init__ when it is set_initialized flag जोड़ें और set होने पर __init__ से जल्दी return करें加一个 _initialized 标志,已设置时就从 __init__ 提前返回
Singleton in multi-threaded code without a lockLock के बिना multi-threaded code में singleton多线程代码中的单例没有加锁Two threads may both see _instance is None and create two objectsदो threads दोनों _instance is None देखकर दो objects बना सकते हैं两个线程可能同时看到 _instance is None,于是创建了两个对象Guard the check with a threading.Lock(), or use a module-level singleton (imports are thread-safe) — threads are an upcoming tutorialजाँच को threading.Lock() से बचाएँ, या module-level singleton लें (imports thread-safe हैं) — threads आने वाले tutorial में用 threading.Lock() 保护检查,或使用模块级单例(导入是线程安全的)— 线程将在后续教程讲解
Making __call__ change self when callers expect no side effectsजब callers side effects की उम्मीद न करें, तब __call__ में self बदलना调用方预期没有副作用时,__call__ 却修改了 selfCallers think obj(x) works like fn(x) — hidden changes surprise themCallers सोचते हैं obj(x) fn(x) जैसा है — छिपे बदलाव चौंकाते हैं调用方以为 obj(x) 和 fn(x) 一样 — 隐藏的变化让人意外Document the side effect clearly, or use a separate method for changesSide effect साफ़ लिखें, या बदलाव के लिए अलग method रखें清楚地写明副作用,或用单独的方法做修改
Using a singleton for state that tests must controlजिस state को tests को control करना हो, उसके लिए singleton对测试需要控制的状态使用单例Tests can't easily reset or replace it — flaky testsTests इसे आसानी से reset या बदल नहीं पाते — अस्थिर tests测试很难重置或替换它 — 测试结果不稳定Pass the object in where it is needed (dependency injection), or reset it in test setupजहाँ ज़रूरत हो वहाँ object पास करें (dependency injection), या test setup में reset करें在需要的地方传入对象(依赖注入),或在测试准备阶段重置它

🩺 Simulator: Bug Doctor🩺 Simulator: Bug Doctor🩺 模拟器:Bug 医生

Five of these mistakes, run for real. Buggy code on the left, fixed code on the right, changed lines marked.

इनमें से पाँच ग़लतियाँ, असली run में। बाईं ओर buggy code, दाईं ओर ठीक किया हुआ, बदली lines चिह्नित।

其中五个错误的真实运行。左边是有 bug 的代码,右边是修正后的代码,改动的行已标出。

Bug DoctorBug DoctorBug 医生5 bugs · real outputs5 bugs · असली outputs5 个 bug · 真实输出
❌ BuggyBuggy有 bug
✅ Fixedठीक किया已修正

SectionSection第 12 节

Quick Reference 📋Quick Reference 📋速查表 📋

Taskकाम任务SyntaxSyntax语法Notesनोट说明
Control object creationObject बनना control करना控制对象创建def __new__(cls, *a, **kw):First argument is cls; must return an objectपहला argument cls; object return करना ज़रूरी第一个参数是 cls;必须 return 一个对象
Use the default creationDefault creation इस्तेमाल करना使用默认创建super().__new__(cls)The standard way to make the bare objectख़ाली object बनाने का मानक तरीक़ा创建空对象的标准方式
Fill in attributesAttributes भरना填充属性def __init__(self, ...):Runs AFTER __new__ — only if it returned an instance of the class__new__ के बाद चलता है — तभी जब उसने class का instance लौटाया在 __new__ 之后运行 — 前提是它返回了该类的实例
Make an instance callableInstance को callable बनाना让实例可调用def __call__(self, ...):Then use obj(args) like a functionफिर obj(args) function की तरह然后像函数一样使用 obj(args)
Basic singletonBasic singleton基本单例Store _instance as a class variable, check it in __new___instance class variable में रखें, __new__ में जाँचें把 _instance 存为类变量,在 __new__ 中检查The simplest and most common patternसबसे आसान और आम pattern最简单、最常见的模式
Safe singletonSafe singleton安全单例Add an _initialized flag, guard __init___initialized flag जोड़ें, __init__ को बचाएँ添加 _initialized 标志,保护 __init__Stops re-initialising on later callsबाद की calls पर दोबारा initialise होना रोकता है防止后续调用重新初始化
Singleton via decoratorDecorator से singleton用装饰器实现单例Wrap the class in a factory functionClass को factory function में लपेटें用工厂函数包装类Short, but the name becomes a function — isinstance breaksछोटा, पर नाम function बन जाता है — isinstance टूटता है简洁,但名字变成了函数 — isinstance 失效
Pythonic singletonPythonic singletonPython 风格的单例Just use a moduleबस एक module直接用模块Modules are cached — natural singletonsModules cache होते हैं — स्वाभाविक singletons模块会被缓存 — 天然的单例
Check if callableCallable है या नहीं检查是否可调用callable(obj)True for functions, classes, and objects whose class defines __call__Functions, classes, और उन objects के लिए True जिनकी class __call__ define करती है对函数、类,以及其类定义了 __call__ 的对象返回 True
Check identityपहचान जाँचना检查身份a is bTrue if both names point to the same objectTrue अगर दोनों नाम एक ही object की ओर हों两个名字指向同一对象时为 True

SectionSection第 13 节

Golden Rules and Quiz 🏆सुनहरे नियम और Quiz 🏆黄金法则与小测验 🏆

🏦 __new__, __call__ and Singletons — Rules to Remember__new__, __call__ और Singletons — याद रखने वाले नियम__new__、__call__ 与单例 — 必须记住的规则
1
Every ClassName(...) call runs two methods: __new__ creates the object, __init__ fills it in. Singletons and immutable subclasses both depend on this order.
हर ClassName(...) call दो methods चलाती है: __new__ object बनाता है, __init__ उसे भरता है। Singletons और immutable subclasses दोनों इसी क्रम पर टिके हैं।
每次 ClassName(...) 调用都会运行 两个方法:__new__ 创建对象,__init__ 填充对象。单例和不可变子类都依赖这个顺序。
2
Don't override __new__ without a reason. The default is right almost every time. Reach for it only for singletons, immutable subclasses of built-ins, or object pools.
बिना वजह __new__ override न करें। Default लगभग हमेशा सही है। इसे सिर्फ़ singletons, built-ins की immutable subclasses, या object pools के लिए लें।
没有理由就不要重写 __new__。默认实现几乎总是对的。只在单例、内置类型的不可变子类或对象池时才使用它。
3
__new__ takes cls, not self — the object doesn't exist yet. It must return the object. Forgetting the return gives the classic 'NoneType' object has no attribute … bug.
__new__ cls लेता है, self नहीं — object अभी है ही नहीं। इसे object लौटाना ही होगा। Return भूलने से क्लासिक 'NoneType' object has no attribute … bug आता है।
__new__ 接收 cls 而不是 self — 对象还不存在。它必须 返回 这个对象。忘记 return 就会出现经典的 'NoneType' object has no attribute … 错误。
4
__init__ runs every time you call ClassName(...) — even when __new__ returned an existing object. For singletons, guard __init__ with an _initialized flag so settings are not overwritten.
ClassName(...) बुलाने पर __init__ हर बार चलता है — तब भी जब __new__ ने मौजूदा object लौटाया। Singletons में __init__ को _initialized flag से बचाएँ ताकि settings न बदलें।
每次调用 ClassName(...),__init__ 都会 运行 — 即使 __new__ 返回的是已有对象。对单例来说,用 _initialized 标志保护 __init__,避免配置被覆盖。
5
__call__ makes an object callable with obj(x). Use it for configured functions (MinLengthValidator(8)) and objects that keep a running state (counters). If the object never carries state, a plain function is clearer.
__call__ object को obj(x) से callable बनाता है। इसे configured functions (MinLengthValidator(8)) और चलती state रखने वाले objects (counters) के लिए लें। अगर object कभी state नहीं रखता, तो सादा function ज़्यादा साफ़ है।
__call__ 让对象可以用 obj(x) 调用。把它用于预先配置的函数(MinLengthValidator(8))和保存累计状态的对象(计数器)。如果对象从不携带状态,普通函数更清晰。
6
A singleton is a class that only ever produces one object. Store it in a class variable (_instance), check it in __new__, and hand back the same object every time. Test with a is b — identity, not equality.
Singleton ऐसी class है जो हमेशा एक ही object बनाती है। उसे class variable (_instance) में रखें, __new__ में जाँचें, और हर बार वही object लौटाएँ। a is b से जाँचें — पहचान, बराबरी नहीं।
单例 是只产生一个对象的类。把它存进类变量(_instance),在 __new__ 中检查,每次返回同一个对象。用 a is b 测试 — 比较身份,而不是相等。
7
Prefer a module over an explicit singleton when you can. A module is run once and cached — from config import settings gives you a natural singleton with no extra code.
जहाँ हो सके, explicit singleton की जगह module लें। Module एक बार चलता है और cache हो जाता है — from config import settings बिना अतिरिक्त code के स्वाभाविक singleton देता है।
能用模块就别写显式单例。模块只运行一次并被缓存 — from config import settings 不用额外代码就得到天然的单例。
8
Singletons in multi-threaded code need a lock. Two threads both seeing _instance is None at the same moment will both create an object. Wrap the check in a threading.Lock(), or use module-level state.
Multi-threaded code में singletons को lock चाहिए। एक ही पल में दो threads _instance is None देखें तो दोनों object बना देंगे। जाँच को threading.Lock() में लपेटें, या module-level state लें।
多线程 代码中的单例需要加锁。两个线程同时看到 _instance is None,就会各自创建一个对象。用 threading.Lock() 包住检查,或使用模块级状态。
9
Singletons make testing harder. They are global state in disguise — hard to reset, hard to replace in tests. Prefer passing the object in (dependency injection) when the code needs testing.
Singletons testing को कठिन बनाते हैं। वे छिपी हुई global state हैं — reset करना और tests में बदलना कठिन। जिस code को test करना हो, वहाँ object को पास करना (dependency injection) बेहतर है।
单例会让测试变难。它们是伪装起来的全局状态 — 难以重置,也难以在测试中替换。需要测试的代码,最好把对象作为参数传入(依赖注入)。
10
When in doubt, ask three questions. Do I need to control creation? → __new__. Should the object be callable like a function? → __call__. Do I need exactly one object across the app? → a singleton (or a module).
शक हो तो तीन सवाल पूछिए। क्या object बनना control करना है? → __new__। क्या object को function की तरह बुलाना है? → __call__। क्या पूरे app में ठीक एक object चाहिए? → singleton (या module)।
拿不准时问三个问题。需要控制创建过程吗?→ __new__。对象需要像函数一样被调用吗?→ __call__。整个应用只需要一个对象吗?→ 单例(或模块)。

Quick Quiz — 8 Questionsछोटा Quiz — 8 सवाल小测验 — 8 道题

🏆 QuizPick an answer to see why.जवाब चुनें और कारण देखें।选一个答案,看看原因。
🎯
Key Takeawayमुख्य सीख关键要点

ClassName(...) runs __new__(cls) to create the object, then __init__(self) to fill it in — but only if __new__ returned an instance of the class. A singleton keeps one object in _instance and returns it from __new__; guard __init__ with a flag, or simply use a module. __call__ lets obj(x) work like a function while the object keeps its state.

ClassName(...) पहले __new__(cls) से object बनाता है, फिर __init__(self) से उसे भरता है — पर तभी जब __new__ ने class का instance लौटाया। Singleton एक object _instance में रखता है और __new__ से वही लौटाता है; __init__ को flag से बचाएँ, या बस module लें। __call__ से obj(x) function की तरह चलता है जबकि object अपनी state रखता है।

ClassName(...) 先运行 __new__(cls) 创建对象,再运行 __init__(self) 填充它 — 前提是 __new__ 返回了该类的实例。单例把唯一的对象存在 _instance 中,并在 __new__ 中返回它;用标志保护 __init__,或者干脆用模块。__call__ 让 obj(x) 像函数一样工作,同时对象保留自己的状态。

🐍 Try Python Yourself

Write, run and visualize Python step by step. No install needed.