十年網(wǎng)站開發(fā)經(jīng)驗 + 多家企業(yè)客戶 + 靠譜的建站團隊
量身定制 + 運營維護+專業(yè)推廣+無憂售后,網(wǎng)站問題一站解決
小編給大家分享一下一篇文章幫你讀懂Python中的self,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

神奇的self:
在Python類中規(guī)定,函數(shù)的第一個參數(shù)是實例對象本身,并且約定俗成,把其名字寫為self。其作用相當于java中的this,表示當前類的對象,可以調(diào)用當前類中的屬性和方法。
class是面向?qū)ο蟮脑O計思想,instance(也即是 object,對象)是根據(jù) class 創(chuàng)建的。
一個類(class)應該包含數(shù)據(jù)和操作數(shù)據(jù)的方法,通俗來講就是屬性和函數(shù)(即調(diào)用方法)。
類 class 中為啥用使用 self ?
在類的代碼(函數(shù))中,需要訪問當前的實例中的變量和函數(shù),即訪問Instance中的:
對應的變量(property):Instance.ProperyNam,去讀取之前的值和寫入新的值。
調(diào)用對應函數(shù)(function):Instance.function(),即執(zhí)行對應的動作。
-> 而需要訪問實例的變量和調(diào)用實例的函數(shù),當然需要對應的實例Instance對象本身。
-> 而Python中就規(guī)定好了,函數(shù)的第一個參數(shù),就必須是實例對象本身,并且建議,約定俗成,把其名字寫為self。
-> 所以,我們需要self(需要用到self)。
首先,在Python中類的定義:
在python中,類是通過關鍵字 class 定義的:
class 后面緊跟類名,即 Person,類名通常大寫字母開頭,緊接著是(object),表示該類是從哪個類繼承下來的,通常,如果沒有合適的 繼承類,就使用 object 類,這是所有類最終都會繼承的類。
class Person(object):
pass將 Person類實例化,創(chuàng)建實例化是通過 類名+() 實現(xiàn)的。
class Person(object):
pass
student = Person() # 創(chuàng)建類的實例化
print(student)
print(Person)
可以看到,變量 student 指向的就是一個 Person的 object,后面的 0x0000026EE434D8D0 是內(nèi)存地址,每個 object 的地址都不一樣,而 Person 本身則是一個類。
也可以給實例變量綁定屬性,比如:為 student 綁定 name 和 score 屬性
class Person(object):
pass
student = Person()
# print(student)
# print(Person)
student.name = "Gavin" # 為實例變量 student 綁定 name 屬性 類似于 賦值 操作
student.score = 100 # 為 其綁定 score 屬性
print(student.name)
print(student.score)
上述的方法雖然可以為類的實例變量綁定屬性,但是不夠方便和elegant , 由于類 可以起到模板的作用,故在創(chuàng)建實例的時候,可以將我們認為必須綁定 屬性 強制填寫進去,在python中,是通過 類中通常都會使用的一個方法,即def __init__(self) 方法,在創(chuàng)建實例變量的時候,就把 name 和 score 等屬性綁上去。
class Person(object):
def __init__(self,name,score):
self.name = name
self.score = score
student = Person('Gavin',100) # 傳入 __init__ 方法中需要的參數(shù)
print(student.name)
print(student.score)
傳入空參數(shù)的情況,會報錯:
class Person(object):
def __init__(self,name,score):
self.name = name
self.score = score
student = Person() # 此處應該有參數(shù)傳入,卻沒有傳
print(student.name)
print(student.score)
注意:
1、__init__ 方法的第一個參數(shù)永遠是 self ,表示創(chuàng)建的實例本身,因此,在 __init__ 方法的內(nèi)部,就可以把各種屬性綁定到 self,因為 self 就指向創(chuàng)建的實例本身。
2、使用了 __init__ 方法,在創(chuàng)建實例的時候就不能傳入 空的參數(shù)了,必須傳入與 __init__ 方法匹配的參數(shù),但是 self 不需要傳,python解釋器會自己把實例變量傳進去。
在類中定義多個函數(shù)相互調(diào)用
class Person(object):
def __init__(self,x,y):
self.x = x
self.y = y
def add(self):
sum = self.x + self.y
return sum
def square(self):
squr = pow(self.x,2)+pow(self.y,2)
return squr
def add_square(self):
c = self.add()+self.square()
return c
student = Person(3,4)
print(student.add())
print(student.square())
print('--------- 我是可愛的分割線-----------')
print(student.add_square())
通過上述的例子可以看出,與普通的函數(shù)相比,在類中定義的函數(shù)只有兩點不同:
1、第一個參數(shù)永遠是 self ,并且調(diào)用時不用傳遞該參數(shù)
2、在類中函數(shù)相互調(diào)用要加 self ,如上例中: c = self.add()+self.square(), 不加 self ,會報錯: 函數(shù)未定義,看下圖:

除此之外,類的方法和普通函數(shù)沒甚區(qū)別,當然也可以使用 默認參數(shù)、可變參數(shù)和關鍵字參數(shù),例子如下:
class Person(object):
def __init__(self,x,y):
self.x = x
self.y = y
def add(self,z=16): # 設置 默認變量 z =16,這只是個普通的局部變量,非實例變量,實例變量需要
self.z = z,這樣定義
sum = self.x + self.y + z
return sum
def square(self):
squr = pow(self.x,2)+pow(self.y,2)
return squr
def add_square(self,z): # 調(diào)用時傳入變量,這也是個普通的局部變量,非實例變量
c = self.add()+self.square() + z
return c
student = Person(3,4)
print(student.add())
print(student.square())
print('--------- 我是可愛的分割線-----------')
print(student.add_square(16))
看了上述的例子可能還是不明白 self 到底是個什么鬼,為啥要使用 self 這鬼東西?沒關系,往下看:
其實 self 這家伙簡單的說就是把 class 中 定義的 變量和函數(shù) 變成 實例變量和實例函數(shù),作為類 class 的成員,使得成員間能互相調(diào)用,而不需要從外部調(diào)用 數(shù)據(jù)(變量)和 方法(函數(shù)),以實現(xiàn)數(shù)據(jù)的封裝,以上面的 Person 類為例:
創(chuàng)建實例的時候需要給出實例變量 x,y, 調(diào)用函數(shù)時給出 z ,調(diào)用很容易,卻不知道內(nèi)部實現(xiàn)的細節(jié)。
總之,類是創(chuàng)建實例的模板,而實例則是一個一個具體的對象,各個實例擁有的數(shù)據(jù)都相互獨立、互不影響;方法是與實例綁定的函數(shù),和普通的函數(shù)不同,方法可以直接訪問實例的數(shù)據(jù)。
其實 self 中存儲的是實例變量和實例函數(shù)的屬性,可以理解為一個字典( dict ),如:{'name':'zhang','age':'18'}就是這些。
注意只有數(shù)據(jù)屬性,并沒有創(chuàng)建新的類的方法。 類----->通過實例化生成----對象---->(對象只是一串類似于字典的數(shù)據(jù),沒有把類的里的方法復制給你,python沒有new這個方法!)
class Person(object):
def __init__(self,x,y):
self.x = x
self.y = y
def add(self,z=16): # 設置 z 為實例變量,即 self.z = z, z 是 class 的一個成員了,而非普通局部變量
self.z = z
sum = self.x + self.y + z # z雖然已被實例化,但是依然可以當作 普通變量來用
return sum
def square(self):
squr = pow(self.x,2)+pow(self.y,2)
return squr
def add_square(self):
c = self.add()+self.square() + self.z # 調(diào)用實例變量 z
return c
student = Person(3,4)
print(student.add())
print(student.square())
print('--------- 我是可愛的分割線-----------')
print(student.add_square())
print(student.z) # 函數(shù)add 中的 z 被實例化以后,就可以利用實例化的方法訪問它
通過這個例子可以看出, z 本來是 add() 函數(shù)的默認形參,通過將其實例化,就可以在其他函數(shù)體內(nèi)調(diào)用實例變量z
被實例化以后,就可以利用實例化的方法訪問它。
那么 self 到底是什么?
class Box(object):
def __init__(self, boxname, size, color):
self.boxname = boxname
self.size = size
self.color = color # self就是用于存儲對象屬性的集合,就算沒有屬性self也是必備的
def open(self, myself):
print('-->用自己的myself,打開那個%s,%s的%s' % (myself.color, myself.size, myself.boxname))
print('-->用類自己的self,打開那個%s,%s的%s' % (self.color, self.size, self.boxname))
def close(self):
print('-->關閉%s,謝謝' % self.boxname)
b = Box('魔盒', '14m', '紅色')
b.close()
b.open(b) # 本來就會自動傳一個self,現(xiàn)在傳入b,就會讓open多得到一個實例對象本身,print看看是什么。
print(b.__dict__) # 這里返回的就是self本身,self存儲屬性,沒有動作。
self代表類的實例,而非類;self 就是 對象/實例 屬性集合
Box 是個類-----》self 實例化------》 b對象/ 實例
class 抽象體------》實例化------》對象/實例,含有屬性:{'boxname':'魔盒', ‘size’:‘14m’, 'color':'red'},即 self
self 看似是整個對象,實際上清楚地描述了類就是產(chǎn)生對象的過程,描述了 self 就是得到了 對象,所以 self 內(nèi)的鍵值可以直接使用
正如自然界中一個有效的對象,必須包括:
1、描述對象的屬性;2、對象的方法
所以 self是必須的,也是對象中重要的特性。
看下面的代碼,感覺就更神奇了:
class Box(object):
def myInit(mySelf, boxname, size, color):
mySelf.boxname = boxname
mySelf.size = size
mySelf.color = color # 自己寫一個初始化函數(shù),一樣奏效,甚至不用self命名。其它函數(shù)當中用標準self
return mySelf # 返回給實例化過程一個對象!神奇!并且含有對象屬性/字典
# def __init__(self, boxname, size, color):
# self.boxname = boxname
# self.size = size
# self.color = color #注釋掉原來標準的初始化
def open(self, myself):
print(self)
print('-->用自己的myself,打開那個%s,%s的%s' % (myself.color, myself.size, myself.boxname))
print('-->用類自己的self,打開那個%s,%s的%s' % (myself.color, myself.size, myself.boxname))
def close(self):
print('-->關閉%s,謝謝' % self.boxname)
# 經(jīng)過改造,運行結(jié)果和標準初始化沒區(qū)別
b = Box().myInit('魔盒', '14m', '紅色')
# b = Box('魔盒', '14m', '紅色')#注釋掉原來標準的初始化方法
b.close()
b.open(b) # 本來就會自動傳一個self,現(xiàn)在傳入b,就會讓open多得到一個實例對象本身,print看看是什么。
print(b.__dict__) # 這里返回的就是self本身,self存儲屬性,沒有動作。
換個角度來講,對類的操作有:
1、定義屬性 ; 2、調(diào)用方法
對類的反饋有:
1、得到屬性 ; 2、執(zhí)行方法
在 class 類的函數(shù)中,為什么 self是必要的,因為 self 是對象的載體,可以理解成一個字典,看下面代碼:
class Box(object):
def myInit(mySelf, boxname, size, color):
print(mySelf.__dict__)#顯示為{}空字典
mySelf.boxname = boxname
mySelf.__dict__['aa'] = 'w'#甚至可以像字典一樣操作
mySelf.size = size
mySelf.color = color # 自己寫一個初始化函數(shù),一樣奏效,甚至不用self命名。其它函數(shù)當中用標準self
return mySelf # 返回給實例化過程一個對象!神奇!并且含有對象屬性/字典
# def __init__(self, boxname, size, color):
# self.boxname = boxname
# self.size = size
# self.color = color #注釋掉原來標準的初始化
def open(self, myself):
print(self)
print('-->用自己的myself,打開那個%s,%s的%s' % (myself.color, myself.size, myself.boxname))
print('-->用類自己的self,打開那個%s,%s的%s' % (myself.color, myself.size, myself.boxname))
def close(self):
print('-->關閉%s,謝謝' % self.boxname)
# 經(jīng)過改造,運行結(jié)果和標準初始化沒區(qū)別
b = Box().myInit('魔盒', '14m', '紅色')
# b = Box('魔盒', '14m', '紅色')#注釋掉原來標準的初始化方法
b.close()
b.open(b) # 本來就會自動傳一個self,現(xiàn)在傳入b,就會讓open多得到一個實例對象本身,print看看是什么。
print(b.__dict__) # 這里返回的就是self本身,self存儲屬性,沒有動作。
注意此處的: mySelf.__dict__['aa'] = 'w' #甚至可以像字典一樣操作; 在 b.__dict__ 的結(jié)果中顯示為:'aa':'w'
故可以把 self 理解成存儲 實例化對象屬性的字典(dict), self 存儲屬性,而沒有動作執(zhí)行。
self總是指調(diào)用時的類的實例。
python 中一些特殊的實例變量:
1、私有變量(private),只有內(nèi)部可以訪問,外部不能訪問,私有變量是在名稱前以兩個下劃線開頭,如:__name,其實私有變量也不是完全不能被外部訪問,不能直接訪問是因為python解釋器對外把 __name 變量改成了 _類名__name,所仍然可以通過 _類名__name 來訪問 __name。
2、在Python中,變量名類似__xxx__的,也就是以雙下劃線開頭,并且以雙下劃線結(jié)尾的,是特殊變量,特殊變量是可以直接訪問的,不是private變量,所以,不能用__name__、__score__這樣的變量名。
3、以一個下劃線開頭的實例變量名,比如_name,這樣的實例變量外部是可以訪問的。
以上是一篇文章幫你讀懂Python中的self的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學習更多知識,歡迎關注創(chuàng)新互聯(lián)成都網(wǎng)站設計公司行業(yè)資訊頻道!
另外有需要云服務器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務器、裸金屬服務器、高防服務器、香港服務器、美國服務器、虛擬主機、免備案服務器”等云主機租用服務以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應用場景需求。