我對python self的總結是:
1.對於成員變數:
子類在初始化過程中,如果進入到父類的初始化函數中,在父類中遇到的self.variable(父類中)都將變成子類的成員變數,即便是在子類中沒有定義這個變數,初始化完成後也可以在子類的成員中調用那個變數。廢話少說,直接上代碼:
from classctob import *
class Extentd(Extentc):
def __init__(self):
super(Extentd, self).__init__()
self.__class__.myglobal='global from d'
##self.name='I am d'
def onStart(self):
print self.name
print self.__class__.myglobal
print self.test
if __name__=='__main__':
d=Extentd()
d.start()
---------------------------------------------------------------------------------------------------------
from classbtoa import *
class Extentc(Extentb):
def __init__(self):
super(Extentc,self).__init__()
self.__class__.myglobal='global from c'
self.name='I am c'
self.test="I'm defined in c!"
def onStart(self):
print self.name
print self.__class__.myglobal
def start(self):
super(Extentc,self).start()
if __name__=='main':
pass
------------------------------------------------------------------------------------
class Basea(object):
'''
basea is base class
'''
myglobal=None
def __init__(self):
self.name='I am basea'
self.__class__.myglobal='global from basea'
print self.__class__.myglobal
def onStart(self):
print self.name
print self.__global
class Extentb(Basea):
def __init__(self):
super(Extentb,self).__init__()
print self.name
print self.__class__.myglobal
self.__class__.__global='global from b'
self.name='I am b'
def onStart(self):
print self.name
print self.__global
def start(self):
self.onStart()
if __name__=='main':
pass
-------------------------------------------------------------------------------
以上代碼的繼承關係是:basea是基類,Extentb(basea),Extentc(Extentb),Extentd(Extentc)
其中Extentc裡定義了變數self.test,這個變數並沒有在Extentd中,但是Extentd卻用print輸出了這個變數的值。
2.對於成員函數:
用self.func代表調用一個成員函數。在《dive into python》中有對self的這樣的描述:“在 __init__
方法中,self
指向新建立的對象;在其它的類方法中,它指向方法被調用的類執行個體”
在以上代碼中d.start()將調用Extentc.start()(因為Extentd中沒有定義start(),只能去父類中找了),這個函數又指向了父類的start(),而在父類中是self.onStart(),此時將會調用Extentb.onStart()嗎?不是!是調用Extentd.onStart()。也就是說繞了一大圈最終還是調的底層子類的onStart()函數。這對於C++程式員會感到有些不適應。這也是python的self不能完全當做C++裡的this的原因。
從以上兩點可以看出python裡的self有多“自私”了吧,它把每一個遇到的變數都據為己有(如果自己沒有的話),每遇到的一個函數調用都先從自身的函數裡找,沒有再去調父類的(這倒有些像重載父類函數了)