国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Python學(xué)習(xí)之路8.2-對(duì)Python類的補(bǔ)充

liukai90 / 2596人閱讀

摘要:本章主要是對(duì)上一章類的補(bǔ)充。對(duì)于多態(tài)的補(bǔ)充子類可以被看成是父類的類型,但父類不能被看成是子類的類型。仍然以類為例,動(dòng)物里有哺乳動(dòng)物,卵生動(dòng)物,有能飛的動(dòng)物和不能飛的動(dòng)物,這是兩種大的分類方式。一般在中,以為結(jié)尾類的都作為接口。

《Python編程:從入門到實(shí)踐》筆記。
本章主要是對(duì)上一章Python類的補(bǔ)充。
1. 從一個(gè)類派生出所有類

上一篇文章說(shuō)道Python類的定義與繼承一般是如下形式:

class A:   # 或者寫成class A():
    pass

class B(A):
    pass

其實(shí),對(duì)于類A,它并不是算是一個(gè)真正意義上的基類,而是和Java類似,Python中所有的類最終都繼承自object類(首字母小寫,比較特殊),所以對(duì)于A的定義可以寫成如下形式:

class A(object):
    pass

只是通常把object給省略了。

2. 訪問(wèn)限制

從上一篇中我們知道,類的屬性可以被直接訪問(wèn),如果需要對(duì)訪問(wèn)做一些限制,我們可以通過(guò)定義相應(yīng)的方法。在Python中,對(duì)于一般的屬性,用C++或Java的話來(lái)說(shuō),它們都是公有屬性,外部可以直接訪問(wèn),比如像下面的這個(gè)name屬性:

class A:
    def __init__(self, name):
        self.name = name

但如果我們?cè)谶@個(gè)屬性前面加兩個(gè)下劃線,將其變成如下形式:

class A:
    def __init__(self, name):
        self.__name = name

那么name就變成了一個(gè)私有屬性,它只能在對(duì)象的內(nèi)部被訪問(wèn),如果想以如下形式訪問(wèn)則會(huì)報(bào)錯(cuò):

# 代碼:
class A:
    -- snip --
    
a = A("test")
print(a.__name)

# 結(jié)果:
AttributeError: "A" object has no attribute "__name"

那是不是真的就訪問(wèn)不到這個(gè)屬性了呢?說(shuō)不清是有幸還是不幸,Python沒(méi)有所謂的真正的私有屬性,Python中類的所有屬性都能被訪問(wèn)。Python解釋器只是將__name換了個(gè)名稱,變成了:

self._A__name

即在前面加了一個(gè)單下劃線和類名。

# 代碼:
class A:
    -- snip --
    
a = A("test")
print(a._A__name)

# 結(jié)果:
test

強(qiáng)烈不建議這樣訪問(wèn)屬性!而且,不同版本的Python解釋器會(huì)將這樣的屬性改成不同的名字。

3. 使用裝飾器(decorator)

在上一點(diǎn)中說(shuō)到了通過(guò)方法來(lái)訪問(wèn)類的屬性,這種方式一般叫做get/set方法,最后在調(diào)用時(shí)調(diào)用的是類的方法,現(xiàn)在我們使用Python內(nèi)置的@property裝飾器來(lái)訪問(wèn)類的屬性,最后在調(diào)用時(shí)是調(diào)用的屬性,實(shí)際上它是將類的方法通過(guò)裝飾器變?yōu)閷傩?。以下是通過(guò)裝飾器和通過(guò)get/set方法來(lái)訪問(wèn)屬性的代碼比較:

class Teacher:
    def __init__(self, name):
        self.name = name

    def get_name(self):
        return self.name

    def set_name(self, name):
        # 可以加上一些限制
        self.name = name

class Student:
    def __init__(self, name):
        self._name = name

    @property
    def name(self):
        return self._name

    @name.setter
    def name(self, name):
        # 可以加上一些限制
        self._name = name

t = Teacher("Miss")
s = Student("Boy")

print(t.get_name())
print(s.name)
t.set_name("Miss Lee")
s.name = "Kevin"

從上述代碼也可以看出,定義的時(shí)候,兩者的代碼量區(qū)別其實(shí)不大,但是在調(diào)用的時(shí)候,明顯使用裝飾器更方便些。

4. 類中其它類型的屬性

類中除了普通的屬性,以及上述的私有屬性,還有前后都有雙下劃線的屬性,例如__xxx__,它們是特殊變量,可以被直接訪問(wèn),不是私有屬性,所以一般不要起__name__,__score__這樣的屬性名,對(duì)于方法也是如此,不光有想__init__()這樣的方法,還有很多前后都有雙下劃線的方法,比如__del__(),它是類的析構(gòu)函數(shù)。在以后的文章中還會(huì)介紹許多這種方法。

不光有雙下劃線的屬性,還有單下劃線的比如 _name,前單下劃線,它表示的意思是:雖然能被訪問(wèn),但請(qǐng)將其看做私有屬性,不要隨便訪問(wèn)。

5. 對(duì)于多態(tài)的補(bǔ)充

子類可以被看成是父類的類型,但父類不能被看成是子類的類型。比如:

# 代碼:
class Animal:
    pass

class Dog(Animal):
    pass

a = Animal()
d = Dog()

print(isinstance(d, Animal))
print(isinstance(a, Dog))

# 結(jié)果:
True
False

也就是說(shuō),如果我們定義了這樣一個(gè)函數(shù):

def animal_run(animal):
    animal.run()

它接收Animal及其子類的所有對(duì)象,只要該類的run()方法正確編寫,Python都能在解釋時(shí)正確調(diào)用相應(yīng)類的run()方法,即調(diào)用方只管調(diào)用animal_run()函數(shù),不用管類的run()方法的細(xì)節(jié),不管是現(xiàn)有的類還是新擴(kuò)展出的子類,只要保證run()正確實(shí)現(xiàn)了,那么animal_run()就是正確的。這就是著名的“開閉原則”:對(duì)擴(kuò)展開放,對(duì)修改封閉。

6. 靜態(tài)語(yǔ)言與動(dòng)態(tài)語(yǔ)言

仍以上面的animal_run()函數(shù)為例。對(duì)于像Java這樣的靜態(tài)語(yǔ)言,傳入的參數(shù)必須是Animal及其子類,否則就無(wú)法調(diào)用run()方法。而對(duì)于像Python這樣的動(dòng)態(tài)語(yǔ)言,傳入的不一定要求是Animal及其子類,只要這個(gè)對(duì)象有run()方法就行了。這就是動(dòng)態(tài)語(yǔ)言的“鴨子類型”,只要“看起來(lái)像鴨子,走起道來(lái)像鴨子”,那它就能被看做是鴨子。Python的“file-like object”就是一種“鴨子類型”,對(duì)于真正的文件對(duì)象,都有一個(gè)read()方法,用于返回文件內(nèi)容。但對(duì)于其他對(duì)象,只要正確實(shí)現(xiàn)了read()方法,即使它不是文件對(duì)象,它也能被看做是文件。

7. 多重繼承與MixIn設(shè)計(jì)

前一篇文章中的繼承是單繼承,但Python和C++一樣,支持多重繼承;Java只支持單繼承,她通過(guò)接口類來(lái)實(shí)現(xiàn)多重繼承的效果。首先需要搞清楚多重繼承為什么存在。仍然以Animal類為例,動(dòng)物里有哺乳動(dòng)物,卵生動(dòng)物,有能飛的動(dòng)物和不能飛的動(dòng)物,這是兩種大的分類方式。如果我們要派生出一個(gè)能飛的哺乳動(dòng)物(比如蝙蝠),如果按照單一繼承,可以按如下方式:

也可以先從Animal繼承出RunnableFlyable兩個(gè)類,再繼承出哺乳類和卵生類(相當(dāng)于將上圖的二三層換了位置),但從這種單繼承可以看出,如果分類增多,類的數(shù)量將呈指數(shù)級(jí)增加。故而一般采用多重繼承的方式:

class Animal:
    pass

class Mammalia(Animal):
    pass

class Flyable:
    def fly(self):
        print("Flying...")

class Bat(Mammalia, Flyable):
    pass

這樣Bat類將具有MammaliaFlyable兩個(gè)父類的所有屬性與方法。一般在Java中,以able為結(jié)尾類的都作為接口。

在設(shè)計(jì)類的繼承的時(shí)候,一般主線都是單一繼承的,像上述例子中的從Animal派生出Manmalia,但如果后續(xù)的類中要混入一些額外的功能,但這功能又不是這個(gè)子類所獨(dú)有的,比如上述的Flyable,那么就可以通過(guò)多重繼承,從ManmaliaRunnable派生出Bat類,這就是MinIn設(shè)計(jì),Java中采用接口來(lái)實(shí)現(xiàn)這種設(shè)計(jì)。

為了更好的看出繼承關(guān)系,一般將RunnableFlyable類的名字改為RunnableMixInFlyableMixIn,同時(shí),還可以定義出肉食動(dòng)物CarnivorousMixIn和植食動(dòng)物HerbivoresMixIn,讓子類同時(shí)擁有好幾個(gè)MinIn

class Dog(Mammalia, RunnableMixIn, CarnivorousMixIn):
    pass

所以在設(shè)計(jì)類時(shí),我們應(yīng)該優(yōu)先考慮通過(guò)多重繼承來(lái)組合多個(gè)MinIn,而不是直接考慮更多層次的繼承關(guān)系。

最后,本篇較多內(nèi)容是根據(jù)廖雪峰老師的博客再理解而來(lái)的,感謝廖雪峰老師!

迎大家關(guān)注我的微信公眾號(hào)"代碼港" & 個(gè)人網(wǎng)站 www.vpointer.net ~

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/41793.html

相關(guān)文章

  • Python學(xué)習(xí)之路30-接口:從協(xié)議到抽象基類

    摘要:本篇內(nèi)容將從鴨子類型的動(dòng)態(tài)協(xié)議,逐漸過(guò)渡到使接口更明確能驗(yàn)證實(shí)現(xiàn)是否符合規(guī)定的抽象基類。抽象基類介紹完動(dòng)態(tài)實(shí)現(xiàn)接口后,現(xiàn)在開始討論抽象基類,它屬于靜態(tài)顯示地實(shí)現(xiàn)接口。標(biāo)準(zhǔn)庫(kù)中的抽象基類從開始,標(biāo)準(zhǔn)庫(kù)提供了抽象基類。 《流暢的Python》筆記。本篇是面向?qū)ο髴T用方法的第四篇,主要討論接口。本篇內(nèi)容將從鴨子類型的動(dòng)態(tài)協(xié)議,逐漸過(guò)渡到使接口更明確、能驗(yàn)證實(shí)現(xiàn)是否符合規(guī)定的抽象基類(Abst...

    LucasTwilight 評(píng)論0 收藏0
  • Python學(xué)習(xí)之路28-符合Python風(fēng)格的對(duì)

    摘要:本篇繼續(xù)學(xué)習(xí)之路,實(shí)現(xiàn)更多的特殊方法以讓自定義類的行為跟真正的對(duì)象一樣。之所以要讓向量不可變,是因?yàn)槲覀冊(cè)谟?jì)算向量的哈希值時(shí)需要用到和的哈希值,如果這兩個(gè)值可變,那向量的哈希值就能隨時(shí)變化,這將不是一個(gè)可散列的對(duì)象。 《流暢的Python》筆記。本篇是面向?qū)ο髴T用方法的第二篇。前一篇講的是內(nèi)置對(duì)象的結(jié)構(gòu)和行為,本篇?jiǎng)t是自定義對(duì)象。本篇繼續(xù)Python學(xué)習(xí)之路20,實(shí)現(xiàn)更多的特殊方法以讓...

    Eric 評(píng)論0 收藏0
  • Python學(xué)習(xí)之路10-測(cè)試代碼

    摘要:也就是說(shuō),你可以將上述代碼中的看做單元測(cè)試,而將看做測(cè)試用例。在測(cè)試類中的每一個(gè)測(cè)試方法都必須以開頭,否則將不會(huì)被認(rèn)定是一個(gè)單元測(cè)試。 《Python編程:從入門到實(shí)踐》筆記。本章主要學(xué)習(xí)如何使用Python標(biāo)準(zhǔn)庫(kù)中的unittest模塊對(duì)代碼進(jìn)行簡(jiǎn)單的測(cè)試。 1. 前言 作為初學(xué)者,并非必須為你嘗試的所有項(xiàng)目編寫測(cè)試;但參與工作量較大的項(xiàng)目時(shí),你應(yīng)對(duì)自己編寫的函數(shù)和類的重要行為進(jìn)行測(cè)...

    huangjinnan 評(píng)論0 收藏0
  • Python學(xué)習(xí)之路10-測(cè)試代碼

    摘要:也就是說(shuō),你可以將上述代碼中的看做單元測(cè)試,而將看做測(cè)試用例。在測(cè)試類中的每一個(gè)測(cè)試方法都必須以開頭,否則將不會(huì)被認(rèn)定是一個(gè)單元測(cè)試。 《Python編程:從入門到實(shí)踐》筆記。本章主要學(xué)習(xí)如何使用Python標(biāo)準(zhǔn)庫(kù)中的unittest模塊對(duì)代碼進(jìn)行簡(jiǎn)單的測(cè)試。 1. 前言 作為初學(xué)者,并非必須為你嘗試的所有項(xiàng)目編寫測(cè)試;但參與工作量較大的項(xiàng)目時(shí),你應(yīng)對(duì)自己編寫的函數(shù)和類的重要行為進(jìn)行測(cè)...

    Developer 評(píng)論0 收藏0
  • Python學(xué)習(xí)之路27-對(duì)象引用、可變性和垃圾回收

    摘要:函數(shù)的參數(shù)作為引用時(shí)唯一支持的參數(shù)傳遞模式是共享傳參,它指函數(shù)的形參獲得實(shí)參中各個(gè)引用的副本,即形參是實(shí)參的別名。而在上面這個(gè)例子中,類的屬性實(shí)際上是形參所指向的對(duì)象所指對(duì)象,的別名。 《流暢的Python》筆記本篇是面向?qū)ο髴T用方法的第一篇,一共六篇。本篇主要是一些概念性的討論,內(nèi)容有:Python中的變量,對(duì)象標(biāo)識(shí),值,別名,元組的某些特性,深淺復(fù)制,引用,函數(shù)參數(shù),垃圾回收,de...

    Batkid 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<