python 模塊, 類和對(duì)象

2021-09-15 14:57 更新

練習(xí)40.模塊, 類和對(duì)象

Python 是一門(mén)“面向?qū)ο缶幊陶Z(yǔ)言”。這意味著在Python中有一個(gè)叫做類的概念,你能通過(guò)類用一種特殊的方式構(gòu)建你的軟件。使用類的概念,能給你的程序增添一致性,這樣你可以用一種很輕松方便的方式調(diào)用他們。至少,這是面向?qū)ο蟮睦碚摗?/p>

我現(xiàn)在要通過(guò)使用你已經(jīng)知道的字典和模塊等來(lái)教你開(kāi)始學(xué)習(xí)面向?qū)ο缶幊獭㈩惡蛯?duì)象。我的問(wèn)題是面向?qū)ο缶幊蹋∣OP)只是普通的怪異。你要為之而奮斗,努力嘗試?yán)斫馕抑v的內(nèi)容,編寫(xiě)代碼,在下一個(gè)練習(xí)中,我會(huì)更深入的講解。

我們要開(kāi)始了。

模塊就像字典

你知道字典是如何被創(chuàng)建以及使用的,它用來(lái)將一個(gè)事物對(duì)應(yīng)到另一個(gè)事物。意思就是說(shuō)如果你有一個(gè)字典,字典中包括一個(gè)key "apple",那么你就可以實(shí)現(xiàn):

mystuff = {'apple': "I AM APPLES!"}
print mystuff['apple']

記住“從X獲取Y”的說(shuō)法,然后想一想模塊(module)。你之前已經(jīng)寫(xiě)過(guò)一些模塊,你應(yīng)該知道它們:

  1. 包含一些函數(shù)和變量的python文件
  2. 你可以導(dǎo)入這個(gè)文件
  3. 你可以用.操作符訪問(wèn)這個(gè)模塊的函數(shù)和變量

想象一下我有一個(gè)叫做mystuff.py的模塊,在這個(gè)模塊中有一個(gè)叫做apple的函數(shù),下面是 mystuff.py 模塊的代碼:

# this goes in mystuff.py
def apple():
    print "I AM APPLES!"

當(dāng)我寫(xiě)完以上代碼,我就可以通過(guò)import來(lái)調(diào)用mystuff模塊,并訪問(wèn)apple函數(shù):

import mystuff
mystuff.apple()

我還可以增加一個(gè)叫做tangerine的變量:

def apple():
    print "I AM APPLES!"

# this is just a variable
tangerine = "Living reflection of a dream"

可以用相同的方法來(lái)訪問(wèn):

import mystuff

mystuff.apple()
print mystuff.tangerine

返回再看字典,你應(yīng)該發(fā)現(xiàn)模塊的使用跟字典是相似的,只不過(guò)語(yǔ)法不同,我們比較一下:

mystuff['apple'] # get apple from dict
mystuff.apple() # get apple from the module
mystuff.tangerine # same thing, it's just a variable

也就是說(shuō)我們?cè)赑ython中有一套通用的模式:

  1. 有一個(gè)key=value模式的容器
  2. 通過(guò)key從容器中獲取數(shù)據(jù)

在字典中,key是一個(gè)字符串,寫(xiě)法為[key],在模塊中,key是一個(gè)標(biāo)識(shí)符,寫(xiě)法為.key,在其余的地方,他們幾乎是一樣的。

類就像模塊

你可以認(rèn)為一個(gè)模塊就是一個(gè)可以存放Python代碼的特殊字典,這樣你就可以通過(guò).操作符訪問(wèn)它。Python還有一個(gè)另外的結(jié)構(gòu)提供相似的功能,就是類(class)。類的作用是組織一系列的函數(shù)和數(shù)據(jù)并將它們放在一個(gè)容器里,這樣你可以通過(guò).操作符訪問(wèn)到它們。

如果我想創(chuàng)建一個(gè)類似mystuff的類,我需要這樣做:

class MyStuff(object):

    def __init__(self):
        self.tangerine = "And now a thousand years between"

    def apple(self):
        print "I AM CLASSY APPLES!"

這相比于模塊復(fù)雜一些,對(duì)比之下肯定會(huì)有不同,但是你應(yīng)該能返現(xiàn)這個(gè)類就像寫(xiě)一個(gè)包含apple()方法的“迷你”mystuff模塊一樣.讓你困惑的地方可能是__init__()這個(gè)方法以及使用self.tangerinetangerine賦值。

這正是為什么要使用類而不是僅有模塊的原因:你可以使用Mystuff這個(gè)類,還可以用它來(lái)創(chuàng)建更多個(gè)Mystuff,而他們之間也不會(huì)互相沖突。當(dāng)你導(dǎo)入一個(gè)模塊時(shí),你的整個(gè)項(xiàng)目也就只有一個(gè)這個(gè)模塊。

在你理解這些之前,你需要明白什么是“對(duì)象”,以及如何像使用Mystuff.py模塊一樣使用Mystuff這個(gè)類。

對(duì)象就像導(dǎo)入

如果一個(gè)類就像一個(gè)迷你模塊,那么類也會(huì)有一個(gè)類似import的概念,這個(gè)概念被稱為實(shí)例化,這只是對(duì)創(chuàng)建一種更虛幻更聰明的叫法。當(dāng)一個(gè)類被實(shí)例化,你就得到一個(gè)類的對(duì)象。

實(shí)例化類的方法就是像調(diào)用函數(shù)一樣調(diào)用這個(gè)類:

thing = MyStuff()
thing.apple()
print thing.tangerine

第一行就是實(shí)例化的操作,這個(gè)操作多像是在調(diào)用一個(gè)函數(shù)啊。當(dāng)然了,python在幕后幫你做了一系列的事情,我?guī)銇?lái)看看具體的調(diào)用步驟:

  1. python 查找 MyStuff() 并確認(rèn)它是你已經(jīng)定義過(guò)的類
  2. python創(chuàng)建一個(gè)空的對(duì)象,該對(duì)象擁有你在類中用def創(chuàng)建的所有函數(shù)
  3. python看你是否創(chuàng)建了__init__函數(shù),如果有,調(diào)用該方法初始化你新創(chuàng)建的空對(duì)象
  4. MyStuff中,__init__方法有一個(gè)額外的變量self,這是python為我創(chuàng)建的一個(gè)空的對(duì)象,我可以在其上設(shè)置變量。
  5. 然后,我給self.tangerine設(shè)置一首歌詞,然后初始化這個(gè)對(duì)象
  6. python可以使用這個(gè)新創(chuàng)建好的對(duì)象,并將其分配給我可以使用的變量thing。

這就是當(dāng)你調(diào)用一個(gè)類的時(shí)候,python做的事情。記住,這并不是把類給你,而是把類作為藍(lán)本來(lái)創(chuàng)建這種類型東西的副本。

我給了你一個(gè)類的簡(jiǎn)單工作原理,這樣你就可以基于你所了解的模塊,建立你對(duì)類的理解。事實(shí)上,在這一點(diǎn)上,類和對(duì)象與模塊是有區(qū)別的:

  • 類是用來(lái)創(chuàng)建迷你模塊的藍(lán)本或定義
  • 實(shí)例化是如何創(chuàng)建這些小模塊,并在同一時(shí)間將其導(dǎo)入。實(shí)例化僅僅是指通過(guò)類創(chuàng)建一個(gè)對(duì)象。
  • 由此產(chǎn)生的迷你模塊被稱為對(duì)象,你可以將其分配給一個(gè)變量,讓它開(kāi)始運(yùn)行

在這一點(diǎn)上,對(duì)象和模塊的表現(xiàn)不同,這只是提供一種讓你理解類和對(duì)象的方法。

從一個(gè)事物中獲取事物

現(xiàn)在我提供給你3中方法從一個(gè)事物中獲取另一個(gè):

# dict style
mystuff['apples']

# module style
mystuff.apples()
print mystuff.tangerine

# class style
thing = MyStuff()
thing.apples()
print thing.tangerine

類的舉例

你應(yīng)該可以看到在這三個(gè)key=value的容器類型有一定的相似性,你也可能有一堆問(wèn)題.記住這些問(wèn)題,下一節(jié)練習(xí)會(huì)訓(xùn)練你關(guān)于“面向?qū)ο蟮脑~匯”。這節(jié)練習(xí)中,我只想讓你輸入這些代碼并保證它能正常運(yùn)行,這樣能讓你再繼續(xù)下一節(jié)練習(xí)之前獲得一些經(jīng)驗(yàn)。

class Song(object):

    def __init__(self, lyrics):
        self.lyrics = lyrics

    def sing_me_a_song(self):
        for line in self.lyrics:
            print line

happy_bday = Song(["Happy birthday to you",
                   "I don't want to get sued",
                   "So I'll stop right there"])

bulls_on_parade = Song(["They rally around tha family",
                        "With pockets full of shells"])

happy_bday.sing_me_a_song()

bulls_on_parade.sing_me_a_song()

你應(yīng)該看到的內(nèi)容

$ python ex40.py
Happy birthday to you
I don't want to get sued
So I'll stop right there
They rally around tha family
With pockets full of shells

附加題

  1. 用本節(jié)學(xué)到的內(nèi)容多寫(xiě)幾首歌,確定你明白你把一個(gè)字符串的列表作為歌詞傳遞進(jìn)去。
  2. 把歌詞放進(jìn)一個(gè)單獨(dú)的變量,再把這個(gè)變量傳遞給類
  3. 看看你能不能讓這個(gè)類做更多的事情,如果沒(méi)什么想法也沒(méi)關(guān)系,試試看,會(huì)有什么
  4. 在網(wǎng)上搜索一些“面向?qū)ο缶幊獭钡馁Y料,嘗試讓你的大腦填滿這些資料。如果這些資料對(duì)你沒(méi)有用,也沒(méi)關(guān)系,這些東西有一半對(duì)我來(lái)說(shuō)也是沒(méi)有意義的。

常見(jiàn)問(wèn)題

Q:為什么我在類里創(chuàng)建__init__或其他函數(shù)的時(shí)候需要使用self?

如果你不實(shí)用self,像這種代碼cheese = 'Frank'就是不明確的. 代碼并不清楚你指的是實(shí)例的cheese屬性,還是一個(gè)叫做cheesed的全局變量。如果你使用self.cheese='Frank'代碼就會(huì)十分清楚你指的就是實(shí)例中的屬性self.cheese.

以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)