【python】详解类class的继承、__init__初始化、super方法
原文鏈接; https://blog.csdn.net/brucewong0516/article/details/79121179?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromBaidu-1.control&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromBaidu-1.control
通過之前四篇的介紹:
- 【python】python中的類,對象,方法,屬性初認識(一)詳見鏈接
- 【python】詳解類class的屬性:類數據屬性、實例數據屬性、特殊的類屬性、屬性隱藏(二)詳見鏈接
- 【python】詳解類class的方法:實例方法、類方法、靜態方法(三)詳見鏈接
- 【python】詳解類class的訪問控制:單下劃線與雙下劃線_(四)詳見鏈接
Python中類相關的一些基本點已經比較完整清晰了,本文繼續深入Python中類的繼承和_ _slots _ _屬性。
1、繼承
- 在Python中,同時支持單繼承與多繼承,一般語法如下:
- 1
- 2
- 實現繼承之后,子類將繼承父類的屬性,也可以使用內建函數insubclass()來判斷一個類是不是另一個類的子孫類:
@author: BruceWong
“”"
class Parent(object):
‘’’
parent class
‘’’
numList = []
def numdiff(self, a, b):
return a-b
class Child(Parent):
pass
c = Child()
# subclass will inherit attributes from parent class
#子類繼承父類的屬性
Child.numList.extend(range(10))
print(Child.numList)
print(“77 - 2 =”, c.numdiff(77, 2))
# built-in function issubclass()
print(issubclass(Child, Parent))
print(issubclass(Child, object))
# bases can show all the parent classes
#bases屬性查看父類
print(‘the bases are:’,Child.bases)
# doc string will not be inherited
#doc屬性不會被繼承
print(Parent.doc)
print(Child.doc)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
代碼的輸出為:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 77 - 2 = 75 True True the bases are: (<class '__main__.Parent'>,) parent <span class="hljs-keyword">class</span>None
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
例子中唯一特別的地方是文檔字符串。文檔字符串對于類,函數/方法,以及模塊來說是唯一的,也就是說doc屬性是不能從父類中繼承來的。
2、繼承中的_ _init_ _
當在Python中出現繼承的情況時,一定要注意初始化函數_init_的行為:
- 如果子類沒有定義自己的初始化函數,父類的初始化函數會被默認調用;但是如果要實例化子類的對象,則只能傳入父類的初始化函數對應的參數,否則會出錯。
- 如果子類定義了自己的初始化函數,而在子類中沒有顯示調用父類的初始化函數,則父類的屬性不會被初始化
- 如果子類定義了自己的初始化函數,在子類中顯示調用父類,子類和父類的屬性都會被初始化
2.1、子類沒有定義自己的初始化函數,父類的初始化函數會被默認調用:
#定義父類:Parent class Parent(object):def __init__(self, name):self.name = nameprint("create an instance of:", self.__class__.__name__)print("name attribute is:", self.name) #定義子類Child ,繼承父類Parent class Child(Parent):pass #子類實例化時,由于子類沒有初始化,此時父類的初始化函數就會默認被調用 #且必須傳入父類的參數name c = Child("init Child")- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
子類實例化時,由于子類沒有初始化,此時父類的初始化函數就會默認被調用,此時傳入父類的參數name,輸出結果為:
create an instance of: Child name attribute is: init Child- 1
- 2
如果不傳入父類的參數name:
class Parent(object):def __init__(self, name):self.name = nameprint("create an instance of:", self.__class__.__name__)print("name attribute is:", self.name)class Child(Parent):
pass
#c = Child(“init Child”)
#print()
c = Child()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
沒有傳入父類name參數的輸出結果會報錯:
Traceback (most recent call last):File “<ipython-input-11-9a7781a6f192>”, line 1, in <module>
runfile(‘C:/Users/BruceWong/.spyder-py3/類的繼承.py’, wdir=‘C:/Users/BruceWong/.spyder-py3’)
File “C:\Anaconda3\lib\site-packages\spyder\utils\site\sitecustomize.py”, line 866, in runfile
execfile(filename, namespace)
File “C:\Anaconda3\lib\site-packages\spyder\utils\site\sitecustomize.py”, line 102, in execfile
exec(compile(f.read(), filename, ‘exec’), namespace)
File “C:/Users/BruceWong/.spyder-py3/類的繼承.py”, line 54, in <module>
c = Child()
TypeError: init() missing 1 required positional argument: 'name’
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
2.2、子類定義了自己的初始化函數,而在子類中沒有顯示調用父類的初始化函數,則父類的屬性不會被初始化
class Parent(object):def __init__(self, name):self.name = nameprint("create an instance of:", self.__class__.__name__)print("name attribute is:", self.name) #子類繼承父類 class Child(Parent):#子類中沒有顯示調用父類的初始化函數def __init__(self):print("call __init__ from Child class") #c = Child("init Child") #print() #將子類實例化 c = Child() print(c.name)- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
在子類中沒有顯示調用父類的初始化函數,則父類的屬性不會被初始化,因而此時調用子類中name屬性不存在:
AttributeError: ‘Child’ object has no attribute ‘name’
File “<ipython-input-12-9a7781a6f192>”, line 1, in <module>
runfile(‘C:/Users/BruceWong/.spyder-py3/類的繼承.py’, wdir=‘C:/Users/BruceWong/.spyder-py3’)
File “C:\Anaconda3\lib\site-packages\spyder\utils\site\sitecustomize.py”, line 866, in runfile
execfile(filename, namespace)
File “C:\Anaconda3\lib\site-packages\spyder\utils\site\sitecustomize.py”, line 102, in execfile
exec(compile(f.read(), filename, ‘exec’), namespace)
File “C:/Users/BruceWong/.spyder-py3/類的繼承.py”, line 56, in <module>
print(c.name)
AttributeError: ‘Child’ object has no attribute 'name’
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
2.3、如果子類定義了自己的初始化函數,顯示調用父類,子類和父類的屬性都會被初始化
class Parent(object):def __init__(self, name):self.name = nameprint("create an instance of:", self.__class__.__name__)print("name attribute is:", self.name)class Child(Parent):
def init(self):
print(“call init from Child class”)
super(Child,self).init(“data from Child”) #要將子類Child和self傳遞進去
#c = Child(“init Child”)
#print()
d = Parent(‘tom’)
c = Child()
print(c.name)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
子類定義了自己的初始化函數,顯示調用父類,子類和父類的屬性都會被初始化的輸出結果:
#實例化父類Parent的結果 create an instance of: Parent name attribute is: tom#實例化子類Child的結果
call init from Child class
#super首先會先使得父類初始化的參數進行實例化
create an instance of: Child
name attribute is: data from Child
data from Child
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
3、super的使用詳解
- super主要來調用父類方法來顯示調用父類,在子類中,一般會定義與父類相同的屬性(數據屬性,方法),從而來實現子類特有的行為。也就是說,子類會繼承父類的所有的屬性和方法,子類也可以覆蓋父類同名的屬性和方法。
c = Child()
c.fun()
c.ffun()
print(Child.Value)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
輸出結果:
This is from Parent This is from Child Hi, Child value- 1
- 2
- 3
但是,有時候可能需要在子類中訪問父類的一些屬性,可以通過父類名直接訪問父類的屬性,當調用父類的方法是,需要將”self”顯示的傳遞進去的方式:
class Parent(object):Value = "Hi, Parent value"def fun(self):print("This is from Parent")class Child(Parent):
Value = “Hi, Child value”
def fun(self):
print(“This is from Child”)
Parent.fun(self) #調用父類Parent的fun函數方法
c = Child()
c.fun()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
輸出結果:
This is from Child This is from Parent #實例化子類Child的fun函數時,首先會打印上條的語句,再次調用父類的fun函數方法- 1
- 2
這種方式有一個不好的地方就是,需要經父類名硬編碼到子類中,為了解決這個問題,可以使用Python中的super關鍵字:
class Parent(object):Value = "Hi, Parent value"def fun(self):print("This is from Parent")class Child(Parent):
Value = “Hi, Child value”
def fun(self):
print(“This is from Child”)
#Parent.fun(self)
super(Child,self).fun() #相當于用super的方法與上一調用父類的語句置換
c = Child()
c.fun()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
輸出結果:
This is from Child This is from Parent #實例化子類Child的fun函數時,首先會打印上條的語句,再次調用父類的fun函數方法- 1
- 2
總結
以上是生活随笔為你收集整理的【python】详解类class的继承、__init__初始化、super方法的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 玩转算法面试-第四章查找值之leetco
- 下一篇: PDFPlumber使用入门+pytho