日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

pythonsuper_用__init __()方法理解Python super()

發(fā)布時間:2025/4/5 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 pythonsuper_用__init __()方法理解Python super() 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

我想了解一下 super()

我們使用的原因super是,可能使用協(xié)作多重繼承的子類將在方法解析順序(MRO)中調(diào)用正確的下一個父類函數(shù)。

在Python 3中,我們可以像這樣調(diào)用它:class ChildB(Base):

def __init__(self):

super().__init__()

在Python 2中,我們需要像這樣使用它:super(ChildB, self).__init__()

沒有超級,您使用多重繼承的能力有限:Base.__init__(self) # Avoid this.

我在下面進(jìn)一步解釋?!斑@段代碼實(shí)際上有什么區(qū)別?:”class ChildA(Base):

def __init__(self):

Base.__init__(self)class ChildB(Base):

def __init__(self):

super(ChildB, self).__init__()

# super().__init__() # you can call super like this in Python 3!

這段代碼的主要區(qū)別在于你在__init__with中獲得了一個間接層super,它使用當(dāng)前類來確定__init__要在MRO中查找的下一個類。

我在規(guī)范問題的答案中說明了這種差異,如何在Python中使用'super'?,它演示了依賴注入和協(xié)作多重繼承。

如果Python沒有 super

這里的代碼實(shí)際上非常等同于super(如何在C中實(shí)現(xiàn),減去一些檢查和回退行為,并轉(zhuǎn)換為Python):class ChildB(Base):

def __init__(self):

mro = type(self).mro() # Get the Method Resolution Order.

check_next = mro.index(ChildB) + 1 # Start looking after *this* class.

while check_next < len(mro):

next_class = mro[check_next]

if '__init__' in next_class.__dict__:

next_class.__init__(self)

break

check_next += 1

寫得更像本機(jī)Python:class ChildB(Base):

def __init__(self):

mro = type(self).mro()

for next_class in mro[mro.index(ChildB) + 1:]: # slice to end

if hasattr(next_class, '__init__'):

next_class.__init__(self)

break

如果我們沒有該super對象,我們必須在任何地方編寫此手動代碼(或重新創(chuàng)建它!)以確保我們在方法解析順序中調(diào)用正確的下一個方法!

超級如何在沒有明確告知調(diào)用方法的哪個類和實(shí)例的情況下在Python 3中執(zhí)行此操作?

它獲取調(diào)用堆棧幀,并找到類(隱式存儲為本地自由變量,__class__使調(diào)用函數(shù)成為類的閉包)和該函數(shù)的第一個參數(shù),該參數(shù)應(yīng)該是通知它的實(shí)例或類要使用的方法解決順序(MRO)。

因為它需要MRO的第一個參數(shù),所以使用super靜態(tài)方法是不可能的。

對其他答案的批評:使用super()可以避免顯式引用基類,這可能很好。。但主要優(yōu)勢在于多重繼承,可以發(fā)生各種有趣的事情。如果您還沒有,請參閱super上的標(biāo)準(zhǔn)文檔。

這是相當(dāng)浪漫的,并沒有告訴我們太多,但重點(diǎn)super是不要避免編寫父類。重點(diǎn)是確保調(diào)用方法解析順序(MRO)中的下一個方法。這在多重繼承中變得很重要。

我會在這里解釋一下。class Base(object):

def __init__(self):

print("Base init'ed")class ChildA(Base):

def __init__(self):

print("ChildA init'ed")

Base.__init__(self)class ChildB(Base):

def __init__(self):

print("ChildB init'ed")

super(ChildB, self).__init__()

讓我們創(chuàng)建一個我們希望在Child之后調(diào)用的依賴項:class UserDependency(Base):

def __init__(self):

print("UserDependency init'ed")

super(UserDependency, self).__init__()

現(xiàn)在記住,ChildB使用超級,ChildA不是:class UserA(ChildA, UserDependency):

def __init__(self):

print("UserA init'ed")

super(UserA, self).__init__()class UserB(ChildB, UserDependency):

def __init__(self):

print("UserB init'ed")

super(UserB, self).__init__()

并且UserA不調(diào)用UserDependency方法:>>> UserA()UserA init'ed

ChildA init'edBase init'ed

<__main__.UserA object at 0x0000000003403BA8>

但是UserB,因為ChildB使用super,確實(shí)!:>>> UserB()UserB init'ed

ChildB init'edUserDependency init'ed

Base init'ed<__main__.UserB object at 0x0000000003403438>

對另一個答案的批評

在任何情況下都不應(yīng)該執(zhí)行以下操作,這是另一個答案所暗示的,因為當(dāng)您繼承ChildB時肯定會出錯:super(self.__class__, self).__init__() # Don't do this. Ever.

(這個答案并不聰明或特別有趣,但盡管評論中有直接的批評和超過17個downvotes,但回答者堅持提出建議,直到一位善良的編輯解決了他的問題。)

說明:那個回答建議像這樣調(diào)用super:super(self.__class__, self).__init__()

這是完全錯誤的。super讓我們在子類中查找MRO中的下一個父級(請參閱本答案的第一部分)。如果你告訴super我們在子實(shí)例的方法中,那么它將在行中查找下一個方法(可能是這個)導(dǎo)致遞歸,可能導(dǎo)致邏輯失敗(在回答者的例子中,它確實(shí))或者RuntimeError當(dāng)遞歸深度時超過了。>>> class Polygon(object):... def __init__(self, id):... self.id = id...>>> class Rectangle(Polygon):...

def __init__(self, id, width, height):... super(self.__class__, self).__init__(id)...

self.shape = (width, height)...>>> class Square(Rectangle):... pass...>>> Square('a', 10, 10)Traceback (most recent call last):

File "", line 1, in

File "", line 3, in __init__TypeError: __init__() missing 2 required positional arguments: 'width' and 'height'

《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀

總結(jié)

以上是生活随笔為你收集整理的pythonsuper_用__init __()方法理解Python super()的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。