日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

Python基礎(chǔ)

 YANG158798 2022-07-14 發(fā)布于北京

第 1/1 

Python語(yǔ)言的誕生

  • Python的作者,Guido von Rossum(吉多·范·羅蘇姆,中國(guó)Python程序員都叫他 龜叔),荷蘭人。1982年,龜叔從阿姆斯特丹大學(xué)獲得了數(shù)學(xué)和計(jì)算機(jī)碩士學(xué)位。然而,盡管他算得上是一位數(shù)學(xué)家,但他更加享受計(jì)算機(jī)帶來(lái)的樂(lè)趣。用他的話說(shuō),雖然擁有數(shù)學(xué)和計(jì)算機(jī)雙料資質(zhì),他總趨向于做計(jì)算機(jī)相關(guān)的工作,并熱衷于做任何和編程相關(guān)的事情。

  • 1989年,為了打發(fā)圣誕節(jié)假期,龜叔開(kāi)始寫(xiě)Python語(yǔ)言的編譯器。Python這個(gè)名字,來(lái)自龜叔所摯愛(ài)的電視劇Monty Python's Flying Circus。他希望這個(gè)新的叫做Python的語(yǔ)言,能符合他的理想:創(chuàng)造一種C和shell之間,功能全面,易學(xué)易用,可拓展的語(yǔ)言。龜叔作為一個(gè)語(yǔ)言設(shè)計(jì)愛(ài)好者,已經(jīng)有過(guò)設(shè)計(jì)語(yǔ)言的嘗試。這一次,也不過(guò)是一次純粹的hacking行為。


Python發(fā)展

  • 1991年,第一個(gè)Python編譯器誕生。它是用C語(yǔ)言實(shí)現(xiàn)的,并能夠調(diào)用C語(yǔ)言的庫(kù)文件。從一出生,Python已經(jīng)具有了 :類(lèi),函數(shù),異常處理,包含表和詞典在內(nèi)的核心數(shù)據(jù)類(lèi)型,以及模塊為基礎(chǔ)的拓展系統(tǒng)。最初的Python完全由龜叔本人開(kāi)發(fā)。Python得到龜叔同事的歡迎。他們迅速的反饋使用意見(jiàn),并參與到Python的改進(jìn)。龜叔和一些同事構(gòu)成Python的核心團(tuán)隊(duì)。他們將自己大部分的業(yè)余時(shí)間用于hack Python。隨后,Python拓 展到研究所之外。Python將許多機(jī)器層面上的細(xì)節(jié)隱藏,交給編譯器處理,并凸顯出邏輯層面的編程思考。Python程 序員可以花更多的時(shí)間用于思考程序的邏輯,而不是具體的實(shí)現(xiàn)細(xì)節(jié)。這一特征吸引了廣大的程序員。Python開(kāi)始流行。


Python 簡(jiǎn)介

  • Python 是一個(gè)高層次的結(jié)合了解釋性、編譯性、互動(dòng)性和面向?qū)ο蟮哪_本語(yǔ)言。

  • Python 的設(shè)計(jì)具有很強(qiáng)的可讀性,相比其他語(yǔ)言經(jīng)常使用英文關(guān)鍵字,其他語(yǔ)言的一些標(biāo)點(diǎn)符號(hào),它具有比其他語(yǔ)言更有特色語(yǔ)法結(jié)構(gòu)。

  • Python 是一種解釋型語(yǔ)言: 這意味著開(kāi)發(fā)過(guò)程中沒(méi)有了編譯這個(gè)環(huán)節(jié)。類(lèi)似于PHP和Perl語(yǔ)言。

  • Python 是交互式語(yǔ)言: 這意味著,您可以在一個(gè) Python 提示符 >>> 后直接執(zhí)行代碼。

  • Python 是面向?qū)ο笳Z(yǔ)言: 這意味著Python支持面向?qū)ο蟮娘L(fēng)格或代碼封裝在對(duì)象的編程技術(shù)。

  • Python 是初學(xué)者的語(yǔ)言:Python 對(duì)初級(jí)程序員而言,是一種偉大的語(yǔ)言,它支持廣泛的應(yīng)用程序開(kāi)發(fā),從簡(jiǎn)單的文字處理到 WWW 瀏覽器再到游戲。


Python 發(fā)展歷史

Python 是由 Guido van Rossum 在八十年代末和九十年代初,在荷蘭國(guó)家數(shù)學(xué)和計(jì)算機(jī)科學(xué)研究所設(shè)計(jì)出來(lái)的。

Python 本身也是由諸多其他語(yǔ)言發(fā)展而來(lái)的,這包括 ABC、Modula-3、C、C++、Algol-68、SmallTalk、Unix shell 和其他的腳本語(yǔ)言等等。

像 Perl 語(yǔ)言一樣,Python 源代碼同樣遵循 GPL(GNU General Public License)協(xié)議。

現(xiàn)在 Python 是由一個(gè)核心開(kāi)發(fā)團(tuán)隊(duì)在維護(hù),Guido van Rossum 仍然占據(jù)著至關(guān)重要的作用,指導(dǎo)其進(jìn)展。

Python 2.7 被確定為最后一個(gè) Python 2.x 版本,它除了支持 Python 2.x 語(yǔ)法外,還支持部分 Python 3.1 語(yǔ)法。


Python 優(yōu)點(diǎn)

  • 1.易于學(xué)習(xí):Python有相對(duì)較少的關(guān)鍵字,結(jié)構(gòu)簡(jiǎn)單,和一個(gè)明確定義的語(yǔ)法,學(xué)習(xí)起來(lái)更加簡(jiǎn)單。

  • 2.易于閱讀:Python代碼定義的更清晰。

  • 3.易于維護(hù):Python的成功在于它的源代碼是相當(dāng)容易維護(hù)的。

  • 4.一個(gè)廣泛的標(biāo)準(zhǔn)庫(kù):Python的最大的優(yōu)勢(shì)之一是豐富的庫(kù),跨平臺(tái)的,在UNIX,Windows和Macintosh兼容很好。

  • 5.互動(dòng)模式:互動(dòng)模式的支持,您可以從終端輸入執(zhí)行代碼并獲得結(jié)果的語(yǔ)言,互動(dòng)的測(cè)試和調(diào)試代碼片斷。

  • 6.可移植:基于其開(kāi)放源代碼的特性,Python已經(jīng)被移植(也就是使其工作)到許多平臺(tái)。

  • 7.可擴(kuò)展:如果你需要一段運(yùn)行很快的關(guān)鍵代碼,或者是想要編寫(xiě)一些不愿開(kāi)放的算法,你可以使用C或C++完成那部分程序,然后從你的Python程序中調(diào)用。

  • 8.數(shù)據(jù)庫(kù):Python提供所有主要的商業(yè)數(shù)據(jù)庫(kù)的接口。

  • 9.GUI編程:Python支持GUI可以創(chuàng)建和移植到許多系統(tǒng)調(diào)用。

  • 10.可嵌入: 你可以將Python嵌入到C/C++程序,讓你的程序的用戶獲得"腳本化"的能力。

Python語(yǔ)言缺點(diǎn)

  • Python語(yǔ)言非常完善,沒(méi)有明顯的短板和缺點(diǎn),唯一的缺點(diǎn)就是執(zhí)行效率慢,這個(gè)是解釋型語(yǔ)言所通有的,同時(shí)這個(gè)缺點(diǎn)也將被計(jì)算機(jī)越來(lái)越強(qiáng)大的性能所彌補(bǔ)。

Python基礎(chǔ)-面向?qū)ο?一)

Python基礎(chǔ)-面向?qū)ο?一)

  • 面向?qū)ο缶幊探榻B

    如今主流的軟件開(kāi)發(fā)思想有兩種:一個(gè)是面向過(guò)程,另一個(gè)是面向?qū)ο?。面向過(guò)程出現(xiàn)得較早,典型代表為C語(yǔ)言,開(kāi)發(fā)中小型項(xiàng)目的效率很高,但是很難適用于如今主流的大中型項(xiàng)目開(kāi)發(fā)場(chǎng)景。面向?qū)ο髣t出現(xiàn)得更晚一些,典型代表為Java或C++等語(yǔ)言,更加適合用于大型開(kāi)發(fā)場(chǎng)景。兩種開(kāi)發(fā)思想各有長(zhǎng)短。

    對(duì)于面向過(guò)程的思想: 需要實(shí)現(xiàn)一個(gè)功能的時(shí)候,看重的是開(kāi)發(fā)的步驟和過(guò)程,每一個(gè)步驟都需要自己親力親為,需要自己編寫(xiě)代碼(自己來(lái)做)

    對(duì)于面向?qū)ο蟮乃枷耄寒?dāng)需要實(shí)現(xiàn)一個(gè)功能的時(shí)候,看重的并不是過(guò)程和步驟,而是關(guān)心誰(shuí)幫我做這件事(偷懶,找人幫我做)

    面向?qū)ο蟮娜筇卣饔校悍庋b性、繼承性、多態(tài)性。

  • 類(lèi)和對(duì)象

    面向?qū)ο缶幊痰?個(gè)非常重要的概念:類(lèi)和對(duì)象

    對(duì)象是面向?qū)ο缶幊痰暮诵?,在使用?duì)象的過(guò)程中,為了將具有共同特征和行為的一組對(duì)象抽象定義,提出了另外一個(gè)新的概念——類(lèi)

    1. 類(lèi)

    我們學(xué)習(xí)編程語(yǔ)言,就是為了模擬現(xiàn)實(shí)世界中的事物,實(shí)現(xiàn)信息化來(lái)提高工作效率。例如銀行的業(yè)務(wù)系統(tǒng)、超市的結(jié)賬系統(tǒng)等,都是如此。

    面向?qū)ο蟮恼Z(yǔ)言當(dāng)中,“類(lèi)”就是用來(lái)模擬現(xiàn)實(shí)事物的。

    那么模擬現(xiàn)實(shí)世界的事物通常從兩方面模擬:

    1.1,屬性:事物的特征描述信息,用于描述某個(gè)特征“是什么”。 靜

    1.2,行為:事物的能力行動(dòng)方案,用于說(shuō)明事物“能做什么”。

    2. 對(duì)象,某一個(gè)具體事物的存在就是對(duì)象,在現(xiàn)實(shí)世界中可以是看得見(jiàn)摸得著的。

    3. 類(lèi)和對(duì)象之間的關(guān)系:類(lèi)就是創(chuàng)建對(duì)象的模板

    4. 練習(xí):區(qū)分類(lèi)和對(duì)象
    奔馳汽車(chē) 類(lèi)
    奔馳smart 類(lèi)
    張三的那輛奔馳smart 對(duì)象
    狗 類(lèi)
    大黃狗 類(lèi)
    李四家那只大黃狗 對(duì)象
    水果 類(lèi)
    蘋(píng)果 類(lèi)
    紅蘋(píng)果 類(lèi)
    紅富士蘋(píng)果 類(lèi)
    我嘴里吃了一半的蘋(píng)果 對(duì)象

    5. 類(lèi)的構(gòu)成

    類(lèi)(Class) 由3個(gè)部分構(gòu)成:
    類(lèi)的名稱:類(lèi)名
    類(lèi)的屬性:一組數(shù)據(jù)
    類(lèi)的方法:允許對(duì)進(jìn)行操作的方法 (行為)

    舉例:

    1)人類(lèi)設(shè)計(jì),只關(guān)心3樣?xùn)|西:
    事物名稱(類(lèi)名):人(Person)
    屬性:身高(height)、年齡(age)...
    方法(行為/功能):跑(run)、打架(fight)...

    狗類(lèi)的設(shè)計(jì)
    類(lèi)名:狗(Dog)
    屬性:品種 、毛色、性別、名字、 腿兒的數(shù)量...
    方法(行為/功能):叫 、跑、咬人、吃、搖尾巴...

    6. 類(lèi)的抽象

    如何把日常生活中的事物抽象成程序中的類(lèi)?

    擁有相同(或者類(lèi)似)屬性和行為的對(duì)象都可以抽像出一個(gè)類(lèi)

    方法:一般名詞都是類(lèi)(名詞提煉法)

    <1>坦克發(fā)射3顆炮彈轟掉了2架飛機(jī):
    坦克--》可以抽象成 類(lèi)
    炮彈--》可以抽象成類(lèi)
    飛機(jī)-》可以抽象成類(lèi)

    <2>小明在公車(chē)上牽著一條叼著熱狗的狗

    小明--》 人類(lèi)
    公車(chē)--》 交通工具類(lèi)
    熱狗--》 食物類(lèi)
    狗--》 狗類(lèi)

  • 定義類(lèi)

    定義一個(gè)類(lèi),格式如下:

    1
    2
    3
    4
    # class Hero: # 經(jīng)典類(lèi)(舊式類(lèi))定義形式
    class Hero(object):   # 新式類(lèi)定義形式
        def info(self):
            print("英雄不問(wèn)出處。")

    說(shuō)明:object 是Python 里所有類(lèi)的最頂級(jí)父類(lèi);

    info是一個(gè)實(shí)例方法,第一個(gè)參數(shù)一般是self,表示實(shí)例對(duì)象本身,當(dāng)然了可以將self換為其它的名字,其作用是一個(gè)變量 這個(gè)變量指向了實(shí)例對(duì)象

  • 創(chuàng)建對(duì)象

    python中,可以根據(jù)已經(jīng)定義的類(lèi)去創(chuàng)建出一個(gè)或多個(gè)對(duì)象。

    對(duì)象名1 = 類(lèi)名()
       對(duì)象名2 = 類(lèi)名()
       對(duì)象名3 = 類(lèi)名()

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    class Hero(object):
        """info 是一個(gè)實(shí)例方法,類(lèi)對(duì)象可以調(diào)用實(shí)例方法,實(shí)例方法的第一個(gè)參數(shù)一定是self"""
        def info(self):
            """當(dāng)對(duì)象調(diào)用實(shí)例方法時(shí),Python會(huì)自動(dòng)將對(duì)象本身的引用做為參數(shù),
                傳遞到實(shí)例方法的第一個(gè)參數(shù)self里"""
            print(self)
            print("self各不同,對(duì)象是出處。")
     
    # Hero這個(gè)類(lèi) 實(shí)例化了一個(gè)對(duì)象  taidamier(泰達(dá)米爾)
    taidamier = Hero()
    # 對(duì)象調(diào)用實(shí)例方法info(),執(zhí)行info()里的代碼
    # . 表示選擇屬性或者方法
    taidamier.info()
     
    print(taidamier)  # 打印對(duì)象,則默認(rèn)打印對(duì)象在內(nèi)存的地址,結(jié)果等同于info里的print(self)
    print(id(taidamier))  # id(taidamier) 則是內(nèi)存地址的十進(jìn)制形式表示
     
    '''輸出結(jié)果
    <__main__.Hero object at 0x7f96ea060e48>
    self各不同,對(duì)象是出處。
    <__main__.Hero object at 0x7f96ea060e48>
    140286148087368
    '''
  • 添加和獲取對(duì)象的屬性

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    class Hero(object):
        """定義了一個(gè)英雄類(lèi),可以移動(dòng)和攻擊"""
        def move(self):
            """實(shí)例方法"""
            print("正在前往事發(fā)地點(diǎn)...")
     
        def attack(self):
            """實(shí)例方法"""
            print("發(fā)出了一招強(qiáng)力的普通攻擊...")
     
    # 實(shí)例化了一個(gè)英雄對(duì)象 泰達(dá)米爾
    taidamier = Hero()
     
    # 給對(duì)象添加屬性,以及對(duì)應(yīng)的屬性值
    taidamier.name = "泰達(dá)米爾"  # 姓名
    taidamier.hp = 2600  # 生命值
    taidamier.atk = 450  # 攻擊力
    taidamier.armor = 200  # 護(hù)甲值
     
    # 通過(guò).成員選擇運(yùn)算符,獲取對(duì)象的屬性值
    print("英雄 %s 的生命值 :%d" % (taidamier.name, taidamier.hp))
    print("英雄 %s 的攻擊力 :%d" % (taidamier.name, taidamier.atk))
    print("英雄 %s 的護(hù)甲值 :%d" % (taidamier.name, taidamier.armor))
     
    # 通過(guò).成員選擇運(yùn)算符,獲取對(duì)象的實(shí)例方法
    taidamier.move()
    taidamier.attack()
     
    '''輸出結(jié)果
    英雄 泰達(dá)米爾 的生命值 :2600
    英雄 泰達(dá)米爾 的攻擊力 :450
    英雄 泰達(dá)米爾 的護(hù)甲值 :200
    正在前往事發(fā)地點(diǎn)...
    發(fā)出了一招強(qiáng)力的普通攻擊...
    '''
  • 在方法內(nèi)通過(guò)self獲取對(duì)象屬性

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    class Hero(object):
        """定義了一個(gè)英雄類(lèi),可以移動(dòng)和攻擊"""
        def move(self):
            """實(shí)例方法"""
            print("正在前往事發(fā)地點(diǎn)...")
     
        def attack(self):
            """實(shí)例方法"""
            print("發(fā)出了一招強(qiáng)力的普通攻擊...")
     
        def info(self):
            """在類(lèi)的實(shí)例方法中,通過(guò)self獲取該對(duì)象的屬性"""
            print("英雄 %s 的生命值 :%d" % (self.name, self.hp))
            print("英雄 %s 的攻擊力 :%d" % (self.name, self.atk))
            print("英雄 %s 的護(hù)甲值 :%d" % (self.name, self.armor))
      
    # 實(shí)例化了一個(gè)英雄對(duì)象 泰達(dá)米爾
    taidamier = Hero()
     
    # 給對(duì)象添加屬性,以及對(duì)應(yīng)的屬性值
    taidamier.name = "泰達(dá)米爾"  # 姓名
    taidamier.hp = 2600  # 生命值
    taidamier.atk = 450  # 攻擊力
    taidamier.armor = 200  # 護(hù)甲值
     
    # 通過(guò).成員選擇運(yùn)算符,獲取對(duì)象的實(shí)例方法
    taidamier.info()  # 只需要調(diào)用實(shí)例方法info(),即可獲取英雄的屬性
    taidamier.move()
    taidamier.attack()
     
    '''輸出結(jié)果
    英雄 泰達(dá)米爾 的生命值 :2600
    英雄 泰達(dá)米爾 的攻擊力 :450
    英雄 泰達(dá)米爾 的護(hù)甲值 :200
    正在前往事發(fā)地點(diǎn)...
    發(fā)出了一招強(qiáng)力的普通攻擊...
    '''

    創(chuàng)建對(duì)象后再去添加屬性有點(diǎn)不合適,有沒(méi)有簡(jiǎn)單的辦法,可以在創(chuàng)建對(duì)象的時(shí)候,就已經(jīng)擁有這些屬性?

  • __init__()方法

    Python的類(lèi)里提供的,兩個(gè)下劃線開(kāi)始,兩個(gè)下劃線結(jié)束的方法,就是魔法方法,__init__()就是一個(gè)魔法方法,通常用來(lái)做屬性初始化 或 賦值 操作。

    如果類(lèi)面沒(méi)有寫(xiě)__init__方法,Python會(huì)自動(dòng)創(chuàng)建,但是不執(zhí)行任何操作,如果為了能夠在完成自己想要的功能,可以自己定義__init__方法,所以一個(gè)類(lèi)里無(wú)論自己是否編寫(xiě)__init__方法,一定有__init__方法。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    class Hero(object):
        def __init__(self):
            """ 方法,用來(lái)做變量初始化 或 賦值 操作,在類(lèi)實(shí)例化對(duì)象的時(shí)候,會(huì)被自動(dòng)調(diào)用"""
            self.name = "泰達(dá)米爾"  # 姓名
            self.hp = 2600  # 生命值
            self.atk = 450  # 攻擊力
            self.armor = 200  # 護(hù)甲值
      
        def move(self):
            """實(shí)例方法"""
            print("正在前往事發(fā)地點(diǎn)...")
      
        def attack(self):
            """實(shí)例方法"""
            print("發(fā)出了一招強(qiáng)力的普通攻擊...")
      
    taidamier = Hero()
    # 實(shí)例化了一個(gè)英雄對(duì)象,并自動(dòng)調(diào)用__init__()方法
    print('姓名:%s,生命值:%d,攻擊力:%d,護(hù)甲值:%d' % (taidamier.name,taidamier.hp,taidamier.atk,taidamier.armor, ))
    # 通過(guò).成員選擇運(yùn)算符,獲取對(duì)象的實(shí)例方法
    taidamier.move()
    taidamier.attack()
    '''運(yùn)行結(jié)果
    姓名:泰達(dá)米爾,生命值:2600,攻擊力:450,護(hù)甲值:200
    正在前往事發(fā)地點(diǎn)...
    發(fā)出了一招強(qiáng)力的普通攻擊...
    '''

    __init__()方法,在創(chuàng)建一個(gè)對(duì)象時(shí)默認(rèn)被調(diào)用,不需要手動(dòng)調(diào)用

    __init__(self)中的self參數(shù),不需要開(kāi)發(fā)者傳遞,python解釋器會(huì)自動(dòng)把當(dāng)前的對(duì)象引用傳遞過(guò)去。

    在類(lèi)的方法里定義屬性的固定值,則每個(gè)對(duì)象實(shí)例變量的屬性值都是相同的。

    一個(gè)游戲里往往有很多不同的英雄,能否讓實(shí)例化的每個(gè)對(duì)象,都有不同的屬性值呢?

  • 有參數(shù)的__init__()方法

    通過(guò)一個(gè)類(lèi),可以創(chuàng)建多個(gè)對(duì)象,就好比 通過(guò)一個(gè)模具創(chuàng)建多個(gè)實(shí)體一樣

    __init__(self)中,默認(rèn)有1個(gè)參數(shù)名字為self,假如在創(chuàng)建對(duì)象時(shí)傳遞了2個(gè)實(shí)參,那么__init__(self)中除了self作為第一個(gè)形參外還需要2個(gè)形參,例如__init__(self,x,y)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    class Hero(object):
        """定義了一個(gè)英雄類(lèi),可以移動(dòng)和攻擊"""
     
        def __init__(self, name, skill, hp, atk, armor):
            """ __init__() 方法,用來(lái)做變量初始化 或 賦值 操作"""
            # 英雄名
            self.name = name
            # 技能
            self.skill = skill
            # 生命值:
            self.hp = hp
            # 攻擊力
            self.atk = atk
            # 護(hù)甲值
            self.armor = armor
     
        def move(self):
            """實(shí)例方法"""
            print("%s 正在前往事發(fā)地點(diǎn)..." % self.name)
     
        def attack(self):
            """實(shí)例方法"""
            print("發(fā)出了一招強(qiáng)力的%s..." % self.skill)
     
        def info(self):
            print("英雄 %s 的生命值 :%d" % (self.name, self.hp))
            print("英雄 %s 的攻擊力 :%d" % (self.name, self.atk))
            print("英雄 %s 的護(hù)甲值 :%d" % (self.name, self.armor))
      
    # 實(shí)例化英雄對(duì)象時(shí),參數(shù)會(huì)傳遞到對(duì)象的__init__()方法里
    taidamier = Hero("泰達(dá)米爾""旋風(fēng)斬"2600450200)
    gailun = Hero("蓋倫""大寶劍"4200260400)
      
    print(gailun)
    print(taidamier)
     
    # 不同對(duì)象的屬性值的單獨(dú)保存
    print(id(taidamier.name))
    print(id(gailun.name))
     
    # 同一個(gè)類(lèi)的不同對(duì)象,實(shí)例方法共享
    print(id(taidamier.move()))
    print(id(gailun.move()))
     
    '''結(jié)果
    <__main__.Hero object at 0x7f5681bde128>
    <__main__.Hero object at 0x7f5681bd9ac8>
    140009521155040
    140009521270576
    泰達(dá)米爾 正在前往事發(fā)地點(diǎn)...
    10722752
    蓋倫 正在前往事發(fā)地點(diǎn)...
    10722752
    '''

    1,在類(lèi)內(nèi)部獲取 屬性 和 實(shí)例方法,通過(guò)self獲??;

    2,在類(lèi)外部獲取 屬性 和 實(shí)例方法,通過(guò)對(duì)象名獲取。

    3,如果一個(gè)類(lèi)有多個(gè)對(duì)象,每個(gè)對(duì)象的屬性是各自保存的,都有各自獨(dú)立的地址;

    4,但是實(shí)例方法是所有對(duì)象共享的,只占用一份內(nèi)存空間。類(lèi)會(huì)通過(guò)self來(lái)判斷是哪個(gè)對(duì)象調(diào)用了實(shí)例方法。

最后修改:2020年3月1日 16:39

Python基礎(chǔ)-面向?qū)ο?二)

  • __str__()方法

    這個(gè)方法是一個(gè)魔法方法 (Magic Method) ,用來(lái)顯示信息

    該方法需要 return 一個(gè)數(shù)據(jù),并且只有self一個(gè)參數(shù),當(dāng)在類(lèi)的外部 print(對(duì)象) 則打印這個(gè)數(shù)據(jù)

    當(dāng)類(lèi)的實(shí)例化對(duì)象如果沒(méi)有__str__ 則默認(rèn)打印 對(duì)象在內(nèi)存的地址。如果擁有 __str__ 方法后,那么打印對(duì)象則打印 __str__ 的返回值。

    查看類(lèi)的文檔說(shuō)明,也就是類(lèi)的注釋:print(Hero.__doc__)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    class Hero(object):
        """定義了一個(gè)英雄類(lèi),可以移動(dòng)和攻擊"""
     
        def __init__(self, name, skill, hp, atk, armor):
            """ __init__() 方法,用來(lái)做變量初始化 或 賦值 操作"""
            # 英雄名
            self.name = name  # 實(shí)例變量
            # 技能
            self.skill = skill
            # 生命值:
            self.hp = hp   # 實(shí)例變量
            # 攻擊力
            self.atk = atk
            # 護(hù)甲值
            self.armor = armor
     
        def move(self):
            """實(shí)例方法"""
            print("%s 正在前往事發(fā)地點(diǎn)..." % self.name)
     
        def attack(self):
            """實(shí)例方法"""
            print("發(fā)出了一招強(qiáng)力的%s..." % self.skill)
      
        def __str__(self):
            """
                這個(gè)方法是一個(gè)魔法方法 (Magic Method) ,用來(lái)顯示信息
                該方法需要 return 一個(gè)數(shù)據(jù),并且只有self一個(gè)參數(shù),當(dāng)在類(lèi)的外部 print(對(duì)象) 則打印這個(gè)數(shù)據(jù)
            """
            return "英雄【%s】的數(shù)據(jù): 生命值 %d, 攻擊力 %d, 護(hù)甲值 %d" % (self.name, self.hp, self.atk, self.armor)
      
    taidamier = Hero("泰達(dá)米爾""旋風(fēng)斬"2600450200)
    gailun = Hero("蓋倫""大寶劍"4200260400)
     
    # 如果沒(méi)有__str__ 則默認(rèn)打印 對(duì)象在內(nèi)存的地址。
    # 當(dāng)類(lèi)的實(shí)例化對(duì)象 擁有 __str__ 方法后,那么打印對(duì)象則打印 __str__ 的返回值。
    print(taidamier) # 英雄【泰達(dá)米爾】的數(shù)據(jù): 生命值 2600, 攻擊力 450, 護(hù)甲值 200
    print(gailun) # 英雄【蓋倫】的數(shù)據(jù): 生命值 4200, 攻擊力 260, 護(hù)甲值 400
     
    # 查看類(lèi)的文檔說(shuō)明,也就是類(lèi)的注釋
    print(Hero.__doc__) # 定義了一個(gè)英雄類(lèi),可以移動(dòng)和攻擊

    在python中方法名如果是__xxxx__()的,那么就有特殊的功能,因此叫做“魔法”方法。

    當(dāng)使用print輸出對(duì)象的時(shí)候,默認(rèn)打印對(duì)象的內(nèi)存地址。如果類(lèi)定義了__str__(self)方法,那么就會(huì)打印從在這個(gè)方法中 return 的數(shù)據(jù)。

    __str__方法通常返回一個(gè)字符串,作為這個(gè)對(duì)象的描述信息

  • __del__()方法

    創(chuàng)建對(duì)象后,python解釋器默認(rèn)調(diào)用__init__()方法;

    當(dāng)刪除對(duì)象時(shí),python解釋器也會(huì)默認(rèn)調(diào)用一個(gè)方法,這個(gè)方法為_(kāi)_del__()方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    class Hero(object):
     
        # 初始化方法
        # 創(chuàng)建完對(duì)象后會(huì)自動(dòng)被調(diào)用
        def __init__(self, name):
            print('__init__方法被調(diào)用')
            self.name = name
     
        # 當(dāng)對(duì)象被刪除時(shí),會(huì)自動(dòng)被調(diào)用
        def __del__(self):
            print("__del__方法被調(diào)用")
            print("%s 被 GM 干掉了..." % self.name)
      
    # 創(chuàng)建對(duì)象
    taidamier = Hero("泰達(dá)米爾")
     
    # 刪除對(duì)象
    print("%d 被刪除1次" % id(taidamier))
    del(taidamier)
     
    print("--" * 10)
      
    gailun = Hero("蓋倫")
    gailun1 = gailun
    gailun2 = gailun
     
    print("%d 被刪除1次" % id(gailun))
    del(gailun)
     
    print("%d 被刪除1次" % id(gailun1))
    del(gailun1)
     
    print("%d 被刪除1次" % id(gailun2))
    del(gailun2)
    '''
    輸出結(jié)果
    __init__方法被調(diào)用
    139881105243440 被刪除1次
    __del__方法被調(diào)用  
    泰達(dá)米爾 被 GM 干掉了...
    --------------------
    __init__方法被調(diào)用
    139881105242488 被刪除1次
    139881105242488 被刪除1次
    139881105242488 被刪除1次
    __del__方法被調(diào)用
    蓋倫 被 GM 干掉了...
    '''

    當(dāng)有變量保存了一個(gè)對(duì)象的引用時(shí),此對(duì)象的引用計(jì)數(shù)就會(huì)加1;

    當(dāng)使用del() 刪除變量指向的對(duì)象時(shí),則會(huì)減少對(duì)象的引用計(jì)數(shù)。如果對(duì)象的引用計(jì)數(shù)不為1,那么會(huì)讓這個(gè)對(duì)象的引用計(jì)數(shù)減1,當(dāng)對(duì)象的引用計(jì)數(shù)為0的時(shí)候,則對(duì)象才會(huì)被真正刪除(內(nèi)存被回收)。

  • 面向?qū)ο髮?shí)例:烤地瓜

    目標(biāo)
    強(qiáng)化面向?qū)ο缶幊痰脑O(shè)計(jì)能力,進(jìn)一步理解類(lèi)、屬性、方法的構(gòu)建場(chǎng)景
    強(qiáng)化對(duì)self的理解,方法中使用self可以獲取和修改屬性

    烤地瓜規(guī)則:
    1.地瓜有自己的狀態(tài),默認(rèn)是生的,地瓜可以進(jìn)行燒烤
    2地瓜有自己燒烤的總時(shí)間,由每次燒烤的時(shí)間累加得出
    3.地瓜燒烤時(shí),需要提供本次燒烤的時(shí)間
    4.地瓜燒烤時(shí),地瓜狀態(tài)隨著燒烤總時(shí)間的變化而改變: [0, 3)生的、[3, 6)半生不熟、[6, 8)熟了、>=8烤糊了
    5.輸出地瓜信息時(shí),可以顯示地瓜的狀態(tài)和燒烤的總時(shí)間

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    # 新型一個(gè)新型類(lèi)SweetPotato
    class SweetPotato(object):
        '''
        烤地瓜的文檔說(shuō)明
        '''
        # 初始化屬性CookeLevel(一共烤的時(shí)間),CookedString(地瓜狀態(tài)),Condiments(調(diào)料列表)
        def __init__(self):
            self.CookedLevel = 0
            self.CookedString = '生的'
            self.Condiments = []
        # 烤地瓜的方法
        def cook(self,time):
            self.CookedLevel += time
            if self.CookedLevel > 8:
                self.CookedString = '烤糊了'
            elif self.CookedLevel > 5:
                self.CookedString = '烤好了'
            elif self.CookedLevel > 3:
                self.CookedString = '烤的半生不熟'
            else:
                self.CookedString = '生的'
        # 添加調(diào)料的方法
        def add_condiments(self,condiments):
            self.Condiments.append(condiments)
        # print的輸出信息
        def __str__(self):
            if len(self.Condiments) > 0:
                str_Condiments = ','.join(self.Condiments) # 列表轉(zhuǎn)字符串
                return '地瓜烤了%d分鐘,%s,調(diào)料是%s' % (self.CookedLevel,self.CookedString,str_Condiments)
            else:
                return '地瓜烤了%d分鐘,%s,沒(méi)有調(diào)料' % (self.CookedLevel, self.CookedString)
     
    print(SweetPotato.__doc__) # 查看類(lèi)的文檔說(shuō)明:烤地瓜的文檔說(shuō)明
    mysweetpotao = SweetPotato() # 實(shí)例化一個(gè)對(duì)象
    mysweetpotao.cook(2)
    print(mysweetpotao) # 地瓜烤了2分鐘,生的,沒(méi)有調(diào)料
     
    mysweetpotao.cook(2)
    mysweetpotao.add_condiments('番茄醬')
    print(mysweetpotao)# 地瓜烤了4分鐘,烤的半生不熟,調(diào)料是番茄醬
     
    mysweetpotao.cook(3)
    mysweetpotao.add_condiments('辣椒醬')
    print(mysweetpotao) # 地瓜烤了7分鐘,烤好了,調(diào)料是番茄醬,辣椒醬
     
    mysweetpotao.cook(2)
    mysweetpotao.add_condiments('芥末')
    print(mysweetpotao) #地瓜烤了9分鐘,烤糊了,調(diào)料是番茄醬,辣椒醬,芥末

最后修改:2020年3月1日 22:21

Python基礎(chǔ)-面向?qū)ο?三)

  • 繼承的概念

    在程序中,繼承描述的是多個(gè)類(lèi)之間的所屬關(guān)系。

    如果一個(gè)類(lèi)A里面的屬性和方法可以復(fù)用,則可以通過(guò)繼承的方式,傳遞到類(lèi)B里。

    那么類(lèi)A就是基類(lèi),也叫做父類(lèi);類(lèi)B就是派生類(lèi),也叫做子類(lèi)。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    # 父類(lèi)
    class A(object):
        def __init__(self):
            self.num = 10
        def sum(self):
            return self.num + 10
     
    # 子類(lèi)
    class B(A):
        pass
     
    = B()
    print(b.num) # 10
    print(b.sum()) # 20
  • 單繼承:子類(lèi)只繼承一個(gè)父類(lèi)

    故事情節(jié):煎餅果子老師傅在煎餅果子界摸爬滾打幾十年,擁有一身精湛的煎餅果子技術(shù),并總結(jié)了一套"古法煎餅果子配方"??墒抢蠋煾的赀~已久,在去世之前希望把自己的配方傳承下去,于是老師傅把配方傳給他的徒弟大貓...

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    # 定義一個(gè)Master父類(lèi)
    class Master(object):
        def __init__(self):
            # 屬性
            self.gufa = '古法煎餅果子配方'
        # 方法
        def make_cake(self):
            print('按照%s制作古法煎餅果子' % self.gufa)
     
    # 定義一個(gè)Prentice子類(lèi),繼承父類(lèi)Master
    class Prentice(Master):
        # 子類(lèi)可以繼承父類(lèi)所有的屬性和方法,哪怕子類(lèi)沒(méi)有自己的屬性和方法,也可以使用父類(lèi)的屬性和方法。
        pass
     
    # 創(chuàng)建子類(lèi)實(shí)例對(duì)象
    = Prentice()
    # 子類(lèi)對(duì)象可以直接使用父類(lèi)的屬性
    print(p.gufa) # 古法煎餅果子配方
    # 子類(lèi)對(duì)象可以直接使用父類(lèi)的方法
    p.make_cake() # 按照古法煎餅果子配方制作古法煎餅果子

    雖然子類(lèi)沒(méi)有定義__init__方法初始化屬性,也沒(méi)有定義實(shí)例方法,但是父類(lèi)有。所以只要?jiǎng)?chuàng)建子類(lèi)的對(duì)象,就默認(rèn)執(zhí)行了那個(gè)繼承過(guò)來(lái)的__init__方法

    子類(lèi)在繼承的時(shí)候,在定義類(lèi)時(shí),小括號(hào)()中為父類(lèi)的名字

    父類(lèi)的屬性、方法,會(huì)被繼承給子類(lèi)

  • 多繼承:子類(lèi)繼承多個(gè)父類(lèi)

    劇情發(fā)展:大貓掌握了師傅的配方,可以制作古法煎餅果子。但是大貓是個(gè)愛(ài)學(xué)習(xí)的好孩子,他希望學(xué)到更多的煎餅果子的做法,于是通過(guò)百度搜索,找到了一家煎餅果子培訓(xùn)學(xué)校。(多繼承)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    # 定義一個(gè)Master父類(lèi)
    class Master(object):
        def __init__(self):
            # 屬性
            self.gufa = '古法煎餅果子配方'
        # 方法
        def make_cake(self):
            print('按照%s制作古法煎餅果子' % self.gufa)
        def eat_master(self):
            print('在師傅家吃飯')
      
    # 定義一個(gè)School父類(lèi)
    class School(object):
        def __init__(self):
            self.gufa = '現(xiàn)代煎餅果子配方'
        def make_cake(self):
            print('按照%s制作現(xiàn)代煎餅果子' % self.gufa)
        def eat_school(self):
            print('在學(xué)校吃飯')
     
    # 定義一個(gè)Prentice子類(lèi),繼承父類(lèi)Master,School
    class Prentice(Master,School):
        # 子類(lèi)可以繼承兩個(gè)父類(lèi)所有的屬性和方法,哪怕子類(lèi)沒(méi)有自己的屬性和方法,也可以使用兩個(gè)父類(lèi)的屬性和方法。
        pass
     
    # 創(chuàng)建子類(lèi)實(shí)例對(duì)象
    = Prentice()
    # 子類(lèi)對(duì)象可以直接使用父類(lèi)的屬性,兩個(gè)父類(lèi)的屬性名相同,默認(rèn)調(diào)用第一個(gè)父類(lèi)
    print(p.gufa) # 古法煎餅果子配方
    # 子類(lèi)對(duì)象可以直接使用父類(lèi)的方法
    p.make_cake() # 按照古法煎餅果子配方制作古法煎餅果子,兩個(gè)父類(lèi)的屬性名相同時(shí),根據(jù)類(lèi)的魔法屬性mro的順序來(lái)查找
     
    # 兩個(gè)父類(lèi)方法不相同時(shí),兩個(gè)都可以調(diào)用出來(lái)
    p.eat_master() # 在師傅家吃飯
    p.eat_school() # 在學(xué)校吃飯
     
    # 注意:如果多個(gè)父類(lèi)中有同名的 屬性和方法,則根據(jù)類(lèi)的魔法屬性mro的順序來(lái)查找
    print(Prentice.__mro__)
    # 結(jié)果(<class '__main__.Prentice'>, <class '__main__.Master'>, <class '__main__.School'>, <class 'object'>)

    多繼承可以繼承多個(gè)父類(lèi),也繼承了所有父類(lèi)的屬性和方法

    注意:如果多個(gè)父類(lèi)中有同名的 屬性和方法,則根據(jù)類(lèi)的魔法屬性mro的順序來(lái)查找

    多個(gè)父類(lèi)中,不重名的屬性和方法,不會(huì)有任何影響。

  • 子類(lèi)重寫(xiě)父類(lèi)的同名屬性和方法

    劇情發(fā)展:大貓掌握了 師傅的配方 和 學(xué)校的配方,通過(guò)研究,大貓?jiān)趦蓚€(gè)配方的基礎(chǔ)上,創(chuàng)建了一種全新的煎餅果子配方,稱之為 "貓氏煎餅果子配方"。(子類(lèi)重寫(xiě)父類(lèi)同名屬性和方法)

    如果子類(lèi)和父類(lèi)的方法名或?qū)傩悦嗤?,則默認(rèn)使用子類(lèi)的,叫 子類(lèi)重寫(xiě)父類(lèi)的同名方法和屬性

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    # 定義一個(gè)Master父類(lèi)
    class Master(object):
        def __init__(self):
            # 屬性
            self.gufa = '古法煎餅果子配方'
        # 方法
        def make_cake(self):
            print('按照%s制作古法煎餅果子' % self.gufa)
        def eat_master(self):
            print('在師傅家吃飯')
      
    # 定義一個(gè)School父類(lèi)
    class School(object):
        def __init__(self):
            self.gufa = '現(xiàn)代煎餅果子配方'
        def make_cake(self):
            print('按照%s制作現(xiàn)代煎餅果子' % self.gufa)
        def eat_school(self):
            print('在學(xué)校吃飯')
     
    # 定義一個(gè)Prentice子類(lèi),繼承父類(lèi)Master,School
    class Prentice(Master,School):
        # 子類(lèi)重寫(xiě)了屬性和方法
        def __init__(self):
            self.gufa = '貓式煎餅果子配方'
        def make_cake(self):
            print('用%s貓式煎餅果子配方制作煎餅果子' %self.gufa)
     
    # 創(chuàng)建子類(lèi)實(shí)例對(duì)象
    = Prentice()
    print(p.gufa) # 貓式煎餅果子配方,子類(lèi)重寫(xiě)了父類(lèi)的屬性,用子類(lèi)的屬性
    p.make_cake() # 用貓式煎餅果子配方貓式煎餅果子配方制作煎餅果子,子類(lèi)重寫(xiě)了父類(lèi)的方法,用子類(lèi)的方法
      
    # 注意:如果重寫(xiě)了父類(lèi)中有屬性或方法,則默認(rèn)使用子類(lèi)的屬性或方法(根據(jù)類(lèi)的魔法屬性mro的順序來(lái)查找)
    print(Prentice.__mro__)
    # 結(jié)果(<class '__main__.Prentice'>, <class '__main__.Master'>, <class '__main__.School'>, <class 'object'>)
  • 子類(lèi)調(diào)用父類(lèi)同名屬性和方法

    劇情發(fā)展:大貓的新配方大受歡迎,但是有些顧客希望也能吃到古法配方和 現(xiàn)代配方 的煎餅果子...(子類(lèi)調(diào)用父類(lèi)的同名屬性和方法)

    如果子類(lèi)和父類(lèi)的方法名或?qū)傩悦嗤?,則默認(rèn)使用子類(lèi)的,叫子類(lèi)重寫(xiě)父類(lèi)的同名方法和屬性

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    # 定義一個(gè)Master父類(lèi)
    class Master(object):
        def __init__(self):
            # 屬性
            self.gufa = '古法煎餅果子配方'
        # 方法
        def make_cake(self):
            print('按照%s制作古法煎餅果子' % self.gufa)
        def eat_master(self):
            print('在師傅家吃飯')
      
    # 定義一個(gè)School父類(lèi)
    class School(object):
        def __init__(self):
            self.gufa = '現(xiàn)代煎餅果子配方'
        def make_cake(self):
            print('按照%s制作現(xiàn)代煎餅果子' % self.gufa)
        def eat_school(self):
            print('在學(xué)校吃飯')
     
    # 定義一個(gè)Prentice子類(lèi),繼承父類(lèi)Master,School
    class Prentice(Master,School):
        # 子類(lèi)重寫(xiě)了屬性和方法
        def __init__(self):
            self.gufa = '貓式煎餅果子配方'
        def make_cake(self):
            print('用%s貓式煎餅果子配方制作煎餅果子' %self.gufa)
        # 獲取Master的屬性和方法
        def make_master_cake(self):
            Master.__init__(self)
            Master.make_cake(self)
     
        # 獲取School 的屬性和方法
        def make_school_cake(self):
            School.__init__(self)
            School.make_cake(self)
      
    # 創(chuàng)建子類(lèi)實(shí)例對(duì)象
    = Prentice()
    print(p.gufa) # 貓式煎餅果子配方,子類(lèi)重寫(xiě)了父類(lèi)的屬性,用子類(lèi)的屬性
    p.make_cake() # 用貓式煎餅果子配方貓式煎餅果子配方制作煎餅果子,子類(lèi)重寫(xiě)了父類(lèi)的方法,用子類(lèi)的方法
      
    # 注意:如果重寫(xiě)了父類(lèi)中有屬性或方法,則默認(rèn)使用子類(lèi)的屬性或方法(根據(jù)類(lèi)的魔法屬性mro的順序來(lái)查找)
    print(Prentice.__mro__)
    # 結(jié)果(<class '__main__.Prentice'>, <class '__main__.Master'>, <class '__main__.School'>, <class 'object'>)
     
    # 調(diào)用Master的屬性和方法
    p.make_master_cake() # 按照古法煎餅果子配方制作古法煎餅果子
    print(p.gufa) # 執(zhí)行Master類(lèi)的__init__方法后,self.kongfu屬性:古法煎餅果子配方
     
    # 調(diào)用School的屬性和方法
    p.make_school_cake() # 按照現(xiàn)代煎餅果子配方制作現(xiàn)代煎餅果子
    print(p.gufa) # 執(zhí)行School類(lèi)的__init__方法后,self.kongfu屬性:現(xiàn)代煎餅果子配方
  • super()的使用

    子類(lèi)繼承了多個(gè)父類(lèi),如果父類(lèi)類(lèi)名修改了,那么子類(lèi)也要涉及多次修改。而且需要重復(fù)寫(xiě)多次調(diào)用,顯得代碼臃腫。

    使用super() 可以逐一調(diào)用所有的父類(lèi)方法,并且只執(zhí)行一次。調(diào)用順序遵循 mro 類(lèi)屬性的順序。

    注意:如果繼承了多個(gè)父類(lèi),且父類(lèi)都有同名方法,則默認(rèn)只執(zhí)行第一個(gè)父類(lèi)的(同名方法只執(zhí)行一次,目前super()不支持執(zhí)行多個(gè)父類(lèi)的同名方法)

    super() 在Python2.3之后才有的機(jī)制,用于通常單繼承的多層繼承。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    # 定義一個(gè)Master父類(lèi)
    class Master(object):
        def __init__(self):
            # 屬性
            self.gufa = '古法煎餅果子配方'
     
        # 方法
        def make_cake(self):
            print('按照%s制作古法煎餅果子' % self.gufa)
     
        def eat_master(self):
            print('在師傅家吃飯')
      
    # 定義一個(gè)School父類(lèi)
    class School(object):
        def __init__(self):
            self.gufa = '現(xiàn)代煎餅果子配方'
     
        def make_cake(self):
            print('按照%s制作現(xiàn)代煎餅果子' % self.gufa)
     
        def eat_school(self):
            print('在學(xué)校吃飯')
      
    # 定義一個(gè)Prentice子類(lèi),繼承父類(lèi)Master,School
    class Prentice(Master, School):
        # 子類(lèi)重寫(xiě)了屬性和方法
        def __init__(self):
            self.gufa = '貓式煎餅果子配方'
     
        def make_cake(self):
            print('用%s制作煎餅果子' % self.gufa)
     
        def make_all_cake(self):
            # 方式1. 指定執(zhí)行父類(lèi)的方法(代碼臃腫)
            # School.__init__(self)
            # School.make_cake(self)
            #
            # Master.__init__(self)
            # Master.make_cake(self)
            #
            # self.__init__()
            # self.make_cake()
     
            # 方法2. super() 帶參數(shù)版本,只支持新式類(lèi)
            # super(Prentice, self).__init__() # 執(zhí)行父類(lèi)的 __init__方法
            # super(Prentice, self).make_cake()
            # self.make_cake()
     
            # 方法3. super()的簡(jiǎn)化版,只支持新式類(lèi)
            super().__init__()  # 執(zhí)行父類(lèi)的 __init__方法
            super().make_cake()  # 執(zhí)行父類(lèi)的 實(shí)例方法
            self.__init__() # 執(zhí)行本類(lèi)的實(shí)例方法
            self.make_cake()  # 執(zhí)行本類(lèi)的實(shí)例方法
      
    # 創(chuàng)建子類(lèi)實(shí)例對(duì)象
    = Prentice()
    print(p.gufa)
    p.make_all_cake()
  • 多層繼承

    劇情發(fā)展:大貓的煎餅果子店非常紅火,終于有一天,他成了世界首富??!但是他也老了,所以他希望把 師傅的配方 和 學(xué)校的配方 以及自己的配方 繼續(xù)傳承下去...(多層繼承)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    # 定義一個(gè)Master父類(lèi)
    class Master(object):
        def __init__(self):
            # 屬性
            self.gufa = '古法煎餅果子配方'
        # 方法
        def make_cake(self):
            print('按照%s制作古法煎餅果子' % self.gufa)
        def eat_master(self):
            print('在師傅家吃飯')
      
    # 定義一個(gè)School父類(lèi)
    class School(object):
        def __init__(self):
            self.gufa = '現(xiàn)代煎餅果子配方'
        def make_cake(self):
            print('按照%s制作現(xiàn)代煎餅果子' % self.gufa)
        def eat_school(self):
            print('在學(xué)校吃飯')
     
    # 定義一個(gè)Prentice子類(lèi),繼承父類(lèi)Master,School
    class Prentice(Master,School):
        # 子類(lèi)重寫(xiě)了屬性和方法
        def __init__(self):
            self.gufa = '貓式煎餅果子配方'
            self.money = 1000 # 億美金
        def make_cake(self):
            print('用%s配方制作煎餅果子' %self.gufa)
        # 獲取Master的屬性和方法
        def make_master_cake(self):
            Master.__init__(self)
            Master.make_cake(self)
     
        # 獲取School 的屬性和方法
        def make_school_cake(self):
            School.__init__(self)
            School.make_cake(self)
    # 新建一個(gè)大貓徒弟的類(lèi),繼承大貓類(lèi)Prentice
    class PrenticePrentice(Prentice):
        pass
     
    # 創(chuàng)建大貓徒弟的實(shí)例對(duì)象
    pp = PrenticePrentice()
    pp.make_cake() # 用貓式煎餅果子配方配方制作煎餅果子
    print(pp.gufa) # 貓式煎餅果子配方
    pp.make_master_cake() # 按照古法煎餅果子配方制作古法煎餅果子
    print(pp.gufa) # 古法煎餅果子配方
    pp.make_school_cake() # 按照現(xiàn)代煎餅果子配方制作現(xiàn)代煎餅果子
    print(pp.gufa) # 現(xiàn)代煎餅果子配方

最后修改:2020年3月2日 03:23

Python基礎(chǔ)-面向?qū)ο?四)

  • 私有權(quán)限

    面向?qū)ο笕筇匦裕悍庋b、繼承、多態(tài)

    封裝的意義

        1,將屬性和方法放到一起做為一個(gè)整體,然后通過(guò)實(shí)例化對(duì)象來(lái)處理;

        2,隱藏內(nèi)部實(shí)現(xiàn)細(xì)節(jié),只需要和對(duì)象及其屬性和方法交互就可以了;

        3,對(duì)類(lèi)的屬性和方法增加 訪問(wèn)權(quán)限控制。

    私有權(quán)限:在屬性名和方法名 前面 加上兩個(gè)下劃線 __

        1,類(lèi)的私有屬性 和 私有方法,都不能通過(guò)對(duì)象直接訪問(wèn),但是可以在本類(lèi)內(nèi)部訪問(wèn);

        2,類(lèi)的私有屬性 和 私有方法,都不會(huì)被子類(lèi)繼承,子類(lèi)也無(wú)法訪問(wèn);

        3,私有屬性 和 私有方法 往往用來(lái)處理類(lèi)的內(nèi)部事情,不通過(guò)對(duì)象處理,起到安全作用。

    劇情發(fā)展: 大貓覺(jué)得配方傳承下去沒(méi)問(wèn)題,但是錢(qián)是辛辛苦苦掙得血汗錢(qián),不想傳給徒弟。(私有權(quán)限)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    # 定義一個(gè)Master父類(lèi)
    class Master(object):
        def __init__(self):
            # 屬性
            self.gufa = '古法煎餅果子配方'
     
        # 方法
        def make_cake(self):
            print('按照%s制作古法煎餅果子' % self.gufa)
     
        def eat_master(self):
            print('在師傅家吃飯')
     
     
    # 定義一個(gè)School父類(lèi)
    class School(object):
        def __init__(self):
            self.gufa = '現(xiàn)代煎餅果子配方'
     
        def make_cake(self):
            print('按照%s制作現(xiàn)代煎餅果子' % self.gufa)
     
        def eat_school(self):
            print('在學(xué)校吃飯')
     
     
    # 定義一個(gè)Prentice子類(lèi),繼承父類(lèi)Master,School
    class Prentice(Master, School):
        # 子類(lèi)重寫(xiě)了屬性和方法
        def __init__(self):
            self.gufa = '貓式煎餅果子配方'
            self.__money = 1000  # 億美金
     
        def make_cake(self):
            print('用%s配方制作煎餅果子' % self.gufa)
     
        # 獲取Master的屬性和方法
        def make_master_cake(self):
            Master.__init__(self)
            Master.make_cake(self)
     
        # 獲取School 的屬性和方法
        def make_school_cake(self):
            School.__init__(self)
            School.make_cake(self)
     
     
    # 新建一個(gè)大貓徒弟的類(lèi),繼承大貓類(lèi)Prentice
    class PrenticePrentice(Prentice):
        pass
     
     
    # 創(chuàng)建大貓徒弟的實(shí)例對(duì)象
    pp = PrenticePrentice()
    pp.make_cake()  # 用貓式煎餅果子配方配方制作煎餅果子
    print(pp.gufa)  # 貓式煎餅果子配方
    pp.make_master_cake()  # 按照古法煎餅果子配方制作古法煎餅果子
    print(pp.gufa)  # 古法煎餅果子配方
    pp.make_school_cake()  # 按照現(xiàn)代煎餅果子配方制作現(xiàn)代煎餅果子
    print(pp.gufa)  # 現(xiàn)代煎餅果子配方
     
    #monye式私有屬性,實(shí)例化繼承不了
    print(pp.__money)  # 繼承大貓的錢(qián),出錯(cuò):AttributeError: 'PrenticePrentice' object has no attribute '__money'

    Python是以屬性命名方式來(lái)區(qū)分,如果在屬性和方法名前面加了2個(gè)下劃線'__',則表明該屬性和方法是私有權(quán)限,否則為公有權(quán)限。

  • 修改私有屬性的值

    如果需要修改一個(gè)對(duì)象的屬性值,通常有2種方法:

        1,對(duì)象名.屬性名 = 數(shù)據(jù) ----> 直接修改

        2,對(duì)象名.方法名() ----> 間接修改

    私有屬性不能直接訪問(wèn),所以無(wú)法通過(guò)第一種方式修改,一般的通過(guò)第二種方式修改私有屬性的值:定義一個(gè)可以調(diào)用的公有方法,在這個(gè)公有方法內(nèi)訪問(wèn)修改。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    # 定義一個(gè)Master父類(lèi)
    class Master(object):
        def __init__(self):
            # 屬性
            self.gufa = '古法煎餅果子配方'
     
        # 方法
        def make_cake(self):
            print('按照%s制作古法煎餅果子' % self.gufa)
     
        def eat_master(self):
            print('在師傅家吃飯')
     
     
    # 定義一個(gè)School父類(lèi)
    class School(object):
        def __init__(self):
            self.gufa = '現(xiàn)代煎餅果子配方'
     
        def make_cake(self):
            print('按照%s制作現(xiàn)代煎餅果子' % self.gufa)
     
        def eat_school(self):
            print('在學(xué)校吃飯')
     
     
    # 定義一個(gè)Prentice子類(lèi),繼承父類(lèi)Master,School
    class Prentice(Master, School):
        # 子類(lèi)重寫(xiě)了屬性和方法
        def __init__(self):
            self.gufa = '貓式煎餅果子配方'
            self.__money = 1000  # 億美金
     
            # 返回私有屬性的值
        def get_money(self):
            return self.__money
        def set_money(self,num):
            self.__money = num
            return num
        def make_cake(self):
            print('用%s配方制作煎餅果子' % self.gufa)
     
        # 獲取Master的屬性和方法
        def make_master_cake(self):
            Master.__init__(self)
            Master.make_cake(self)
     
        # 獲取School 的屬性和方法
        def make_school_cake(self):
            School.__init__(self)
            School.make_cake(self)
     
     
    # 新建一個(gè)大貓徒弟的類(lèi),繼承大貓類(lèi)Prentice
    class PrenticePrentice(Prentice):
        pass
     
     
    # 創(chuàng)建大貓徒弟的實(shí)例對(duì)象
    pp = PrenticePrentice()
    print(pp.get_money())
    # 可以通過(guò)訪問(wèn)公有方法set_money()來(lái)獲取私有屬性的值
    pp.set_money(2000)
    # 可以通過(guò)訪問(wèn)公有方法get_money()來(lái)修改私有屬性的值
    print(pp.get_money())
  • 多態(tài)

    大家應(yīng)該聽(tīng)說(shuō)過(guò)這樣的故事:有一個(gè)中醫(yī)世家,父親是當(dāng)?shù)匾晃环浅S忻睦洗蠓?看病看的非常好,兒子從小就跟著父親學(xué)醫(yī),醫(yī)術(shù)也不錯(cuò). 突然縣太爺家的千金生了重病,急需老大夫前去治病,但是老大夫又不在家,就請(qǐng)了老大夫的兒子前去給治病. 最后兒子也把病給治好了

    那么,在python語(yǔ)言中能不能做類(lèi)似的事情,比如說(shuō) 在需要調(diào)用父類(lèi)對(duì)象方法的地方,我們也可以調(diào)用子類(lèi)對(duì)象的方法呢?

    當(dāng)然可以! 要想這樣,我們需要使用接下來(lái)要學(xué)習(xí)的知識(shí)點(diǎn):多態(tài).

    好,下面我們就開(kāi)始正式講解 多態(tài).在講解的時(shí)候:

    1.先講解"多態(tài)"的概念

    2.再講解如何使用多態(tài)

    3.最后講解多態(tài)的好處

  • 什么是多態(tài)?

    在需要使用父類(lèi)對(duì)象的地方,也可以使用子類(lèi)對(duì)象, 這種情況就叫多態(tài).

    比如, 在函數(shù)中,我需要調(diào)用 某一個(gè)父類(lèi)對(duì)象的方法, 那么我們也可以在這個(gè)地方調(diào)用子類(lèi)對(duì)象的方法.

  • 如何在程序中使用多態(tài)?

    可以按照以下幾個(gè)步驟來(lái)寫(xiě)代碼:

    1.子類(lèi)繼承父類(lèi)

    2.子類(lèi)重寫(xiě)父類(lèi)中的方法

    3.通過(guò)對(duì)象調(diào)用這個(gè)方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    class Father(object):
        def cure(self):
            print('父親給人治病')
     
    class Son(Father):
        # 重新cure方法
        def cure(self):
            print('兒子給人治病')
     
    # 義函數(shù),在里面 調(diào)用醫(yī)生的cure函數(shù)
    def call_cure(doctor):
        # 調(diào)用醫(yī)生治病的方法
        doctor.cure()
     
    # 創(chuàng)建父類(lèi)對(duì)象
    father = Father()
    # 調(diào)用函數(shù),把父類(lèi)對(duì)象傳遞函數(shù)
    call_cure(father)
     
     
    # 創(chuàng)建子類(lèi)對(duì)象
    son = Son()
    # 調(diào)用函數(shù),把子類(lèi)對(duì)象傳遞函數(shù)
    call_cure(son)
  • 使用多態(tài)的好處dt.png

    多態(tài)的好處:給call_cure(doctor)函數(shù)傳遞哪個(gè)對(duì)象,在它里面就會(huì)調(diào)用哪個(gè)對(duì)象的cure()方法,也就是說(shuō)在它里面既可以調(diào)用son對(duì)象的cure()方法,也能調(diào)用father對(duì)象的cure()方法,當(dāng)然了也可以在它里面調(diào)用Father類(lèi)其它子類(lèi)對(duì)象的cure()方法,這樣可以讓call_cure(doctor)函數(shù)變得更加靈活,額外增加了它的功能,提高了它的擴(kuò)展性.

  • 類(lèi)屬性和實(shí)例屬性

    在了解了類(lèi)基本的東西之后,下面看一下python中這幾個(gè)概念的區(qū)別。

    先來(lái)談一下類(lèi)屬性和實(shí)例屬性:

    在前面的例子中我們接觸到的就是實(shí)例屬性(對(duì)象屬性),顧名思義,類(lèi)屬性就是類(lèi)對(duì)象所擁有的屬性,它被所有類(lèi)對(duì)象的實(shí)例對(duì)象所共有,在內(nèi)存中只存在一個(gè)副本,這個(gè)和C++中類(lèi)的靜態(tài)成員變量有點(diǎn)類(lèi)似。對(duì)于公有的類(lèi)屬性,在類(lèi)外可以通過(guò)類(lèi)對(duì)象和實(shí)例對(duì)象訪問(wèn)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class People(object):
        name = 'Tom'  # 公有的類(lèi)屬性
        __age = 12  # 私有的類(lèi)屬性
     
    = People()
     
    print(p.name)  # 正確
    print(People.name)  # 正確
    print(p.__age)  # 錯(cuò)誤,不能在類(lèi)外通過(guò)實(shí)例對(duì)象訪問(wèn)私有的類(lèi)屬性
    print(People.__age) # 錯(cuò)誤,不能在類(lèi)外通過(guò)類(lèi)對(duì)象訪問(wèn)私有的類(lèi)屬性
  • 實(shí)例屬性(對(duì)象屬性)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    class People(object):
        address = '廣東'  # 類(lèi)屬性
        def __init__(self):
            self.name = 'xiaowang'  # 實(shí)例屬性
            self.age = 20  # 實(shí)例屬性
     
    = People()
    p.age = 12  # 實(shí)例屬性
    print(p.address)  # 正確
    print(p.name)  # 正確
    print(p.age)  # 正確
     
    print(People.address)  # 正確,類(lèi)屬性
    print(People.name)  # 錯(cuò)誤,不是類(lèi)屬性
    print(People.age)  # 錯(cuò)誤,不是類(lèi)屬性
  • 通過(guò)實(shí)例(對(duì)象)去修改類(lèi)屬性

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    class People(object):
        country = 'china' #類(lèi)屬性
     
     
    print(People.country)
    = People()
    print(p.country)
    p.country = 'japan'  # 增加一個(gè)跟類(lèi)屬性同名的實(shí)例屬性,就相當(dāng)于修改了類(lèi)屬性
    print(p.country)  # 實(shí)例屬性會(huì)屏蔽掉同名的類(lèi)屬性
    print(People.country)
    del p.country  # 刪除實(shí)例屬性
    print(p.country)

    總結(jié):如果需要在類(lèi)外修改類(lèi)屬性,必須通過(guò)類(lèi)對(duì)象去引用然后進(jìn)行修改。如果通過(guò)實(shí)例對(duì)象去引用,會(huì)產(chǎn)生一個(gè)同名的實(shí)例屬性,這種方式修改的是實(shí)例屬性,不會(huì)影響到類(lèi)屬性,并且之后如果通過(guò)實(shí)例對(duì)象去引用該名稱的屬性,實(shí)例屬性會(huì)強(qiáng)制屏蔽掉類(lèi)屬性,即引用的是實(shí)例屬性,除非刪除了該實(shí)例屬性。

  • 類(lèi)方法

    是類(lèi)對(duì)象所擁有的方法,需要用修飾器@classmethod來(lái)標(biāo)識(shí)其為類(lèi)方法,對(duì)于類(lèi)方法,第一個(gè)參數(shù)必須是類(lèi)對(duì)象,一般以cls作為第一個(gè)參數(shù)(當(dāng)然可以用其他名稱的變量作為其第一個(gè)參數(shù),但是大部分人都習(xí)慣以'cls'作為第一個(gè)參數(shù)的名字,就最好用'cls'了),能夠通過(guò)實(shí)例對(duì)象和類(lèi)對(duì)象去訪問(wèn)。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    class People(object):
        country = 'china'
     
        #類(lèi)方法,用classmethod來(lái)進(jìn)行修飾
        @classmethod
        def get_country(cls):
            return cls.country
     
    = People()
    print(p.get_country())    #可以用過(guò)實(shí)例對(duì)象引用
    print(People.get_country())    #可以通過(guò)類(lèi)對(duì)象引用

    類(lèi)方法還有一個(gè)用途就是可以對(duì)類(lèi)屬性進(jìn)行修改:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    class People(object):
        country = 'china'
     
        #類(lèi)方法,用classmethod來(lái)進(jìn)行修飾
        @classmethod
        def get_country(cls):
            return cls.country
     
        @classmethod
        def set_country(cls,country):
            cls.country = country
     
     
    = People()
    print(p.get_country())   # china 可以用過(guò)實(shí)例對(duì)象訪問(wèn)
    print(People.get_country())    # china 可以通過(guò)類(lèi)訪問(wèn)
     
    p.set_country('japan')
     
    print(p.get_country()) # japan 
    print(People.get_country()) # japan

    結(jié)果顯示在用類(lèi)方法對(duì)類(lèi)屬性修改之后,通過(guò)類(lèi)對(duì)象和實(shí)例對(duì)象訪問(wèn)都發(fā)生了改變

  • 靜態(tài)方法

    需要通過(guò)修飾器@staticmethod來(lái)進(jìn)行修飾,靜態(tài)方法不需要多定義參數(shù),可以通過(guò)對(duì)象和類(lèi)來(lái)訪問(wèn)。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    class People(object):
        country = 'china'
     
        @staticmethod
        #靜態(tài)方法
        def get_country():
            return People.country
     
     
    = People()
    # 通過(guò)對(duì)象訪問(wèn)靜態(tài)方法
    print(p.get_country()) # china
     
    # 通過(guò)類(lèi)訪問(wèn)靜態(tài)方法
    print(People.get_country()) # china

    總結(jié):

    從類(lèi)方法和實(shí)例方法以及靜態(tài)方法的定義形式就可以看出來(lái),類(lèi)方法的第一個(gè)參數(shù)是類(lèi)對(duì)象cls,那么通過(guò)cls引用的必定是類(lèi)對(duì)象的屬性和方法;

    實(shí)例方法的第一個(gè)參數(shù)是實(shí)例對(duì)象self,那么通過(guò)self引用的可能是類(lèi)屬性、也有可能是實(shí)例屬性(這個(gè)需要具體分析),不過(guò)在存在相同名稱的類(lèi)屬性和實(shí)例屬性的情況下,實(shí)例屬性優(yōu)先級(jí)更高。

    靜態(tài)方法中不需要額外定義參數(shù),因此在靜態(tài)方法中引用類(lèi)屬性的話,必須通過(guò)類(lèi)實(shí)例對(duì)象來(lái)引用

最后修改:2020年3月2日 22:03

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類(lèi)似文章 更多