亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Python中的super().__init__()用法詳解

 更新時(shí)間:2025年06月13日 10:16:51   作者:kanhao100  
我們?cè)趯W(xué)習(xí)Python類的時(shí)候,總會(huì)碰見書上的類中有__init__()這樣一個(gè)函數(shù),這篇文章主要介紹了Python中的super().__init__()用法的相關(guān)資料,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下

基本概念

class SingleConv(nn.Module):
    def __init__(self):
        super(SingleConv, self).__init__()
        self.conv = nn.Conv2d(3, 16, kernel_size=3, padding=1)
    
    def forward(self, x):
        return self.conv(x)

super(SingleConv, self).__init__() 這行代碼用于調(diào)用父類(基類)的初始化方法。具體來說,它讓 SingleConv 類調(diào)用其父類 nn.Module 的 __init__() 方法,確保父類被正確初始化。

這是面向?qū)ο缶幊讨欣^承機(jī)制的重要組成部分,特別是在構(gòu)建 PyTorch 神經(jīng)網(wǎng)絡(luò)模型時(shí)尤為關(guān)鍵。

語法分解

讓我們逐部分解析這個(gè)表達(dá)式:

  • super() - 這是 Python 內(nèi)置函數(shù),用于返回一個(gè)代理對(duì)象,該對(duì)象將方法調(diào)用委托給父類或兄弟類。

  • super(SingleConv, self) - 這部分創(chuàng)建了一個(gè)代理對(duì)象,指向 SingleConv 類的父類(在這個(gè)例子中是 nn.Module)。第一個(gè)參數(shù)指定類本身,第二個(gè)參數(shù)通常是類的實(shí)例(即 self)。

  • super(SingleConv, self).__init__() - 通過代理對(duì)象調(diào)用父類的 __init__() 方法,確保父類的初始化代碼被執(zhí)行。

為什么這很重要?

一般繼承原則

在繼承關(guān)系中,子類需要確保父類被正確初始化,因?yàn)椋?/p>

  • 父類可能設(shè)置了子類依賴的重要屬性和狀態(tài)
  • 父類可能執(zhí)行了必要的初始化邏輯
  • 如果不調(diào)用父類的初始化方法,繼承鏈就會(huì)斷開,子類將無法完全繼承父類的功能

在 PyTorch 中的特殊重要性

在 PyTorch 的 nn.Module 上下文中,調(diào)用 super().__init__() 尤為關(guān)鍵,因?yàn)椋?/p>

  • 參數(shù)管理 - nn.Module 的初始化方法設(shè)置了追蹤和管理模型參數(shù)(如卷積層的權(quán)重和偏置)的機(jī)制

  • 模塊注冊(cè) - 它建立了子模塊的注冊(cè)系統(tǒng),使 PyTorch 能夠識(shí)別模型的層次結(jié)構(gòu)

  • 功能支持 - 它啟用了許多核心功能,包括:

    • 參數(shù)遷移(使用 .to(device) 將模型移動(dòng)到 CPU/GPU)
    • 模型保存和加載(使用 torch.save() 和 torch.load()
    • 訓(xùn)練和評(píng)估模式切換(.train() 和 .eval()
    • 自動(dòng)求導(dǎo)支持

如果省略會(huì)發(fā)生什么?

如果您省略 super().__init__() 調(diào)用,可能會(huì)導(dǎo)致:

class SingleConvWithoutSuper(nn.Module):
    def __init__(self):
        # 沒有調(diào)用 super().__init__()
        self.conv = nn.Conv2d(3, 16, kernel_size=3, padding=1)
    
    def forward(self, x):
        return self.conv(x)

model = SingleConvWithoutSuper()
print(list(model.parameters()))  # 可能返回空列表,因?yàn)閰?shù)沒有被正確注冊(cè)

這樣的模型會(huì)出現(xiàn)多種問題:

  • 參數(shù)不會(huì)被正確注冊(cè)和跟蹤
  • 無法正常使用 .to(device) 遷移到 GPU
  • 保存和加載模型時(shí)可能丟失參數(shù)
  • 梯度可能無法正確傳播

Python 3 的簡(jiǎn)化語法

在 Python 3 中,可以使用更簡(jiǎn)潔的語法:

class SingleConv(nn.Module):
    def __init__(self):
        super().__init__()  # 簡(jiǎn)化版,等效于 super(SingleConv, self).__init__()
        self.conv = nn.Conv2d(3, 16, kernel_size=3, padding=1)
    
    def forward(self, x):
        return self.conv(x)

這種寫法功能完全相同,但更簡(jiǎn)潔易讀。Python 3 的 super() 不帶參數(shù)時(shí)會(huì)自動(dòng)使用當(dāng)前類和實(shí)例。

多重繼承中的作用

在涉及多重繼承的復(fù)雜情況下,super() 特別有用。它會(huì)按照方法解析順序(MRO)正確調(diào)用父類,避免同一個(gè)父類被初始化多次:

class A:
    def __init__(self):
        print("A init")

class B(A):
    def __init__(self):
        super().__init__()
        print("B init")

class C(A):
    def __init__(self):
        super().__init__()
        print("C init")

class D(B, C):
    def __init__(self):
        super().__init__()
        print("D init")

當(dāng)創(chuàng)建 D 的實(shí)例時(shí),super() 確保每個(gè)父類的 __init__ 只被調(diào)用一次,遵循 Python 的 MRO 規(guī)則。

執(zhí)行結(jié)果

當(dāng)我們創(chuàng)建 D 類的實(shí)例(如 d = D())時(shí),輸出結(jié)果為:

A init
C init
B init
D init

這個(gè)輸出順序可能看起來有些反直覺,特別是 C init 出現(xiàn)在 B init 之前,盡管在 D 的繼承聲明中 B 是第一個(gè)父類。讓我們深入分析這是為什么。

方法解析順序 (MRO)

Python 使用一種稱為方法解析順序(Method Resolution Order, MRO)的機(jī)制來確定多重繼承中方法查找的順序。MRO 決定了當(dāng)調(diào)用 super() 時(shí),Python 應(yīng)該按照什么順序查找父類的方法。

我們可以通過以下方式查看一個(gè)類的 MRO:

print(D.__mro__)  # 或者 print(D.mro())

對(duì)于我們的例子,D 類的 MRO 是:

(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)

這意味著 Python 在 D 的實(shí)例上查找方法時(shí),會(huì)按照 D -> B -> C -> A -> object 的順序搜索。

super() 的工作原理

理解 super() 的關(guān)鍵在于:super() 不是簡(jiǎn)單地調(diào)用父類的方法,而是調(diào)用 MRO 中當(dāng)前類之后的下一個(gè)類的方法

當(dāng)在一個(gè)類中使用 super().__init__() 時(shí),Python 會(huì)查找 MRO 中當(dāng)前類之后的下一個(gè)類,并調(diào)用其 __init__ 方法。這是一個(gè)非常強(qiáng)大的機(jī)制,尤其是在處理復(fù)雜的繼承結(jié)構(gòu)時(shí)。

詳細(xì)的執(zhí)行流程

讓我們逐步追蹤 D() 創(chuàng)建實(shí)例時(shí)的執(zhí)行流程:

  • 調(diào)用 D.__init__()

    • 執(zhí)行 super().__init__()
    • 根據(jù) MRO,D 之后的類是 B,所以調(diào)用 B.__init__()
  • 進(jìn)入 B.__init__()

    • 執(zhí)行 super().__init__()
    • 根據(jù) MRO,B 之后的類是 C,所以調(diào)用 C.__init__()
  • 進(jìn)入 C.__init__()

    • 執(zhí)行 super().__init__()
    • 根據(jù) MRO,C 之后的類是 A,所以調(diào)用 A.__init__()
  • 進(jìn)入 A.__init__()

    • 打印 "A init"
    • A.__init__() 執(zhí)行完畢,返回到 C.__init__()
  • 回到 C.__init__()

    • 打印 "C init"
    • C.__init__() 執(zhí)行完畢,返回到 B.__init__()
  • 回到 B.__init__()

    • 打印 "B init"
    • B.__init__() 執(zhí)行完畢,返回到 D.__init__()
  • 回到 D.__init__()

    • 打印 "D init"
    • D.__init__() 執(zhí)行完畢

圖解說明

下面是繼承結(jié)構(gòu)和執(zhí)行順序的圖解:

    A
   / \
  B   C
   \ /
    D

執(zhí)行順序(箭頭表示調(diào)用方向):

D.__init__() → B.__init__() → C.__init__() → A.__init__()
                                                 ↓
D.__init__() ← B.__init__() ← C.__init__() ← 返回并打印 "A init"
     ↓              ↓              ↓
     ↓              ↓         打印 "C init"
     ↓         打印 "B init"
打印 "D init"

與直接調(diào)用父類方法的對(duì)比

為了理解 super() 的價(jià)值,讓我們看看如果不使用 super() 而是直接調(diào)用父類的 __init__ 方法會(huì)發(fā)生什么:

class A:
    def __init__(self):
        print("A init")

class B(A):
    def __init__(self):
        A.__init__(self)  # 直接調(diào)用 A.__init__
        print("B init")

class C(A):
    def __init__(self):
        A.__init__(self)  # 直接調(diào)用 A.__init__
        print("C init")

class D(B, C):
    def __init__(self):
        B.__init__(self)  # 直接調(diào)用 B.__init__
        C.__init__(self)  # 直接調(diào)用 C.__init__
        print("D init")

使用這種方式,創(chuàng)建 D 的實(shí)例將輸出:

A init  # 從 B.__init__ 調(diào)用
B init
A init  # 從 C.__init__ 調(diào)用,A 被初始化了兩次!
C init
D init

可以看到,A.__init__() 被調(diào)用了兩次!這可能導(dǎo)致資源重復(fù)分配、狀態(tài)不一致或其他問題。

總結(jié)

super(SingleConv, self).__init__() 這行代碼是確保 PyTorch 神經(jīng)網(wǎng)絡(luò)模塊正確初始化的關(guān)鍵步驟。它調(diào)用父類 nn.Module 的初始化方法,設(shè)置必要的內(nèi)部狀態(tài),并啟用 PyTorch 的核心功能。

在 Python 3 中,推薦使用更簡(jiǎn)潔的 super().__init__() 語法。無論使用哪種形式,確保在每個(gè)繼承自 nn.Module 的類的 __init__ 方法中調(diào)用它,這是構(gòu)建正確功能的 PyTorch 模型的基礎(chǔ)。

簡(jiǎn)單來說,這行代碼就像告訴您的類:“在我開始自己的初始化工作之前,請(qǐng)確保我從父類繼承的所有功能都已正確設(shè)置好。”

到此這篇關(guān)于Python中的super().__init__()用法詳解的文章就介紹到這了,更多相關(guān)Python中super().__init__()內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論