時(shí)間:2022-10-23 14:07:45 來源:洛陽尚賢科技
做軟件,是要給人用的,人在用之前是沒有數(shù)據(jù)的,但人用了就有數(shù)據(jù),這就需要用到類,把共性的元素抽象出來形成母版。然后基于這個(gè)母版,在人用的時(shí)候產(chǎn)生數(shù)據(jù)。
面向?qū)ο蟮?步是做類,類是連接現(xiàn)實(shí)與虛擬的一座橋梁。 光有這個(gè)橋沒用,因?yàn)樗痪唧w,所以得具體化之后,形成一個(gè)對(duì)象,讓對(duì)象成為現(xiàn)實(shí)控制現(xiàn)實(shí)。寫類的時(shí)候,滿腦子都是如可抽象出共性,類就出來了; 當(dāng)從類到對(duì)象的時(shí)候,又要滿腦子想具體化。 為什么要先抽象再具體? 因?yàn)橹挥邢瘸橄笤倬唧w,才能建立起橋梁來表現(xiàn)具體化的東西, 這是為了在虛擬的世界中掌握現(xiàn)實(shí)!
類:一個(gè)抽象的概念,即生活中的 “類別”
對(duì)象:類的具體實(shí)例,即歸屬某個(gè)類別的 “個(gè)體”
類是創(chuàng)建對(duì)象的 “模板”,它有兩成員:
——數(shù)據(jù)成員:名詞類型的狀態(tài)。 即變量。
——方法成員:動(dòng)詞類型的行為。 即函數(shù)。
1、程序執(zhí)行到類后,類中的代碼只是存儲(chǔ)到了內(nèi)存中,并不會(huì)執(zhí)行,所以它叫代碼區(qū)。
2.1、創(chuàng)建對(duì)象時(shí),在內(nèi)存中所開的空間大小,取決于init方法中的實(shí)例變量的數(shù)量,比如有三個(gè)就是三塊地。這三塊地,就是類的屬性。比如品牌價(jià)格之類的
2.2、創(chuàng)建對(duì)象時(shí),除了在內(nèi)存中開辟空間之外,它還在調(diào)用 init 這個(gè)函數(shù)。 調(diào)函數(shù)就會(huì)開棧幀,開一個(gè) init的棧幀。 在這個(gè)棧幀里開多少空間,就看init中的對(duì)象實(shí)例變量數(shù)量。示例中有3個(gè)。其實(shí)是4個(gè),還有個(gè)self.
2.3、創(chuàng)建對(duì)象填參數(shù)時(shí),為什么不把self加上? init 中的 self是位置形參,那么調(diào)用函數(shù)填參數(shù)時(shí)得是必填的。其實(shí)不是沒加,因?yàn)樵趧?chuàng)建對(duì)象時(shí)python已經(jīng)自動(dòng)給 init 中的self 加上了一個(gè)對(duì)象地址。 只不過這是自動(dòng)的你看不見。 而 init 中的self 也只有一個(gè)功能,就只是存儲(chǔ)對(duì)象地址。 即:把你創(chuàng)建的對(duì)象的地址,存到init中的self里。讓 init 中的 self 知道這是哪一個(gè)對(duì)象在給他存信息。
2.4、因此,之所以自動(dòng)創(chuàng)建對(duì)象地址傳給init 函數(shù)中的self, 是因?yàn)閟elf只是用于存儲(chǔ)對(duì)象地址的。那這個(gè)init 中的self 名字還可以自定義,但這個(gè)位置本身是python“征收” 了必須有的。
2.6、self是怎么接收到對(duì)象地址的呢? 看看init 下面的實(shí)例變量的格式就知道。 它通過一個(gè)點(diǎn), self.變量名, 就是這樣找到變量地址,再通過變量地址找到對(duì)應(yīng)的其它幾個(gè)參數(shù)。 self. 點(diǎn)方法也可以,點(diǎn)實(shí)例變量也可以。
3、所以,整個(gè)棧幀存在的價(jià)值,就是給變量賦值,然后棧幀就銷毀了。
4、棧幀雖然銷毀了,它但的作用已經(jīng)起到了,此時(shí)對(duì)象就知道自己的信息了
5、對(duì)象創(chuàng)建后,開始調(diào)用函數(shù)。在調(diào)用函數(shù)時(shí),為什么語法是 aa.bb() 呢,因?yàn)檫@是語法要求, 它其實(shí)本質(zhì)上就是 bb(aa)。 也就是把對(duì)象做為實(shí)參,傳入到bb這個(gè)函數(shù)的形參里。 所以, 就是說對(duì)象在調(diào)用函數(shù)時(shí),會(huì)把自己做為參數(shù)傳給函數(shù)中的self.
5.1、即然又調(diào)函數(shù),那就會(huì)給這個(gè)函數(shù)開一個(gè)棧幀。這個(gè)棧幀只有一個(gè)空間,也就是self這個(gè)參數(shù),這個(gè)self指向的與對(duì)象指向的是一樣的,因?yàn)閷?duì)象和self存的是同一個(gè)變量地址。
當(dāng)再創(chuàng)建對(duì)象,并調(diào)用函數(shù)時(shí)。一切又重來一遍。
總結(jié):一個(gè)函數(shù)怎么知道又找蘋果,又找華為? 因?yàn)閷?duì)于不同的對(duì)象來說,一個(gè)函數(shù)的棧幀接收到的self不同。
是它能表達(dá)不同對(duì)象、不同數(shù)據(jù)。 什么意思呢? 比如在面向過程中,想表達(dá)一個(gè)人名,name = ‘ 小花 ’ 即使它是在全局變量中,這個(gè)name也只能表示小花一個(gè)人,無法表達(dá)其他人。 想表達(dá)多個(gè),怎么辦,即使做個(gè)列表,那也是死的。
但是類里面的實(shí)例變量,可是能表示無數(shù)人的,因?yàn)轭惪梢詣?chuàng)建無數(shù)對(duì)象。所以,實(shí)例變量能表達(dá)不同對(duì)象、不同數(shù)據(jù)。 所以,面向?qū)ο竽艹蔀橹髁鞯木幊趟枷搿?br />
class Abc( ):
def __init__(self):
self.a = 10 # 這里寫成10,上面不做參數(shù),前面的照樣也是實(shí)例變量。因?yàn)閷?shí)例變量的語法是 對(duì)象—點(diǎn)兒—等號(hào)后面跟數(shù)據(jù)
最后舉個(gè)例子,先來看面向過程 按格式打印列表中的字典;
list_commodity = [
{'cid': 1001, 'name': '小紅', 'price': 10000},
{'cid': 1002, 'name': '小藍(lán)', 'price': 10000},
{'cid': 1003, 'name': '小花', 'price': 52100},
{'cid': 1004, 'name': '小紫', 'price': 20},
{'cid': 1005, 'name': '小白', 'price': 30},
]
def print_single_commodity(item):
print(f"編號(hào){item['cid']}:, 商品名稱{item['name']}, 價(jià)格{item[‘price']}")
def print_commodity():
for commodity in list_commodity:
print_single_commodity(commodity)
print_commodity()
再來看面向?qū)ο?,?shí)現(xiàn)同樣功能 (區(qū)別在于,面向?qū)ο髸r(shí),“母版”可以被無數(shù)對(duì)象使用,比如“編號(hào)、名稱、價(jià)格” 這些共性的元素。
class ListCommodity(object):
def __init__(self, cid, name, price):
self.cid = cid
self.name = name
self.price = price
list_commodity = [
ListCommodity(1001, '小紅', 10000),
ListCommodity(1002, '小藍(lán)', 10000),
ListCommodity(1003, '小花', 52100),
ListCommodity(1004, '小紫', 20),
ListCommodity(1005, '小白', 30),
]
def print_single_commodity(item):
print(f"編號(hào){item.cid}:, 商品名稱{item.name}, 價(jià)格{item.price}”)
def print_commodity():
for commodity in list_commodity:
print_single_commodity(commodity)
print_commodity()
手機(jī):18537972228
電話:0379-64321586
Email:shangxian@sxglpx.com
地址:洛陽市澗西區(qū)九都西路181號(hào)中弘中央廣場D座2705室