1、self的含義
類是抽象的模板,實例是根據類創建出的一個個具體對象。
下面代碼中,andy_1.run() 會被python解釋器轉化爲 Dog.run(andy_1),可以看到對象 andy_1 被傳給了參數 self,用於表明是Dog類的哪個對象在調用run方法。
這種指明是Dog類的哪個對象在調用run方法,被稱爲將run方法綁定到andy_1 對象。
這就是爲什麼類中定義的函數(包括__init__),都要用self作爲第一個參數,就是用來接受具體的對象。特別說明的是,不一定非要用self做參數名,用a b c等任意變量名均可,self只是約定俗成的習慣。
即便是被系統自動調用的函數,如__init__,系統也會將要初始化的對象傳遞給__init__方法的 self 參數。(__init__並不是c++中的構造方法,d=Dog(‘andy’) 實際會等價於 d=object.__new__(Dog),Dog.__init__(d, ‘andy’) 兩條語句,即調用init前,對象已經被創建完成。)
class Dog(object):
def __init__(self, name):
self.name = name
def run(self):
print self.name, 'is running'
andy_1 = Dog('andy_1')
andy_1.run()
andy_2 = Dog('andy_2')
andy_2.run()
2、子類調用父類的函數
子類調用父類有兩種方式:通過父類名 或 通過super函數。
我們用最常見的是調用父類的 __init__()方法說明。
(1)使用父類名
實際上使用了python解釋器的方式調用類的函數,即將父類的 init 函數綁定到b1上。注意 A.__init__(self) 這行代碼中,self參數實際已經被賦值爲 b1 對象。
class A(object):
def __init__(self):
print 'in A init'
class B(A):
def __init__(self):
A.__init__(self)
b1 = B()
這種方式有一個缺點,當子類的父類變化爲其他類時,所有顯示使用父類名的地方都要被修改爲新的父類名。因此,推薦使用super 函數的方式調用父類函數。
(2)使用super函數:super(type, [type-or-object])
super函數返回的不一定是父類,實際是MRO表中下一個類。:
super做的是下面這件事
def super(cls, inst):
mro_list = inst.__class__.mro()
return mro_list[mro_list.index(cls) + 1]
兩個參數 cls 和 inst 分別做了兩件事:
1. inst 負責生成 MRO 的 list
2. 通過 cls 定位當前 MRO 中的 index,並返回 mro[index + 1]
舉例:
class A(object):
def __init__(self):
print 'in A init'
class B(A):
def __init__(self):
super(B, self).__init__()
b = B()