首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 更多程式設計知識

Python __new__ 與 __init__ 差異深度解析:實例建立流程、新式類與經典類、物件創建可控性

     編輯:更多程式設計知識

Python 物件實例化涉及 __new__ 與 __init__ 兩個關鍵方法。__new__ 負責建立實例(配置記憶體),__init__ 負責初始化實例。本文深入剖析兩者調用順序、參數差異、返回值約束、新式類與經典類差異,並示範自訂實例建立邏輯。

新式類 vs 經典類

特性經典類 (Python 2)新式類 (Python 2 繼承 object / Python 3 預設)
定義class A:class A(object):
繼承搜尋深度優先 (DLR)廣度優先 (MRO/C3)
__slots__不支援支援
__getattribute__無有
__new__無內建
__class__ 屬性間接取得直接取得

實例建立流程

  1. 呼叫 ClassName(...) 觸發 __new__
  2. __new__(cls, *args, **kwargs) 接收類別物件 cls (type 類型)
  3. __new__ 必須回傳實例 (通常呼叫 super().__new__(cls) 或 object.__new__(cls))
  4. 回傳的實例作為 self 傳給 __init__
  5. __init__(self, *args, **kwargs) 初始化實例屬性
  6. 最終回傳實例給呼叫者

程式碼驗證調用順序


class Display(object):
    def __init__(self, *args, **kwargs):
        print("init")

    def __new__(cls, *args, **kwargs):
        print("new")
        print(type(cls))  # 
        return object.__new__(cls, *args, **kwargs)

a = Display()
# 輸出:
# new
# 
# init

跨類別借用 __new__


class Another(object):
    def __new__(cls, *args, **kwargs):
        print("newano")
        return object.__new__(cls, *args, **kwargs)

class Display(object):
    def __init__(self, *args, **kwargs):
        print("init")
    def __new__(cls, *args, **kwargs):
        print("newdis")
        return Another.__new__(cls, *args, **kwargs)

a = Display()
# 輸出:
# newdis
# newano
# init

結論:__new__ 決定實例的「出生」,__init__ 決定實例的「成長」;兩者可解耦。

實際應用場景

  • 單例模式:在 __new__ 控制實例唯一性
  • 不可變物件:__new__ 建立後凍結狀態
  • 物件池/快取:__new__ 回傳現有實例
  • 子類別替換:__new__ 依參數回傳不同子類實例
  • 元類配合:__new__ 在類別建立時介入

單例模式範例


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

a = Singleton()
b = Singleton()
print a is b  # True

關鍵差異總結表

維度__new____init__
調用時機實例建立前實例建立後
第一參數cls (類別物件)self (實例物件)
必須回傳實例 (否則 __init__ 不被調用)無 (忽略返回值)
可被繼承是是
常見用途控制建立、單例、不可變、子類分派屬性初始化、資源獲取
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved