最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python超細(xì)致探究面向?qū)ο?/h1>
 更新時(shí)間:2022年06月28日 10:31:15   作者:五包辣條!  
面向?qū)ο缶幊淌且环N編程方式,此編程方式的落地需要使用“類(lèi)”和 “對(duì)象”來(lái)實(shí)現(xiàn),所以,面向?qū)ο缶幊唐鋵?shí)就是對(duì) “類(lèi)”和“對(duì)象” 的使用,今天給大家介紹下python 面向?qū)ο箝_(kāi)發(fā)及基本特征,感興趣的朋友一起看看吧

前言

面向?qū)ο缶幊虒?duì)初學(xué)者來(lái)說(shuō)不難理解但很難應(yīng)用,雖然我們?yōu)榇蠹铱偨Y(jié)過(guò)面向?qū)ο蟮娜阶叻椒ǎǘx類(lèi)、創(chuàng)建對(duì)象、給對(duì)象發(fā)消息),但是說(shuō)起來(lái)容易做起來(lái)難。大量的編程練習(xí)和閱讀優(yōu)質(zhì)的代碼可能是這個(gè)階段最能夠幫助到大家的兩件事情。 接下來(lái)我們還是通過(guò)經(jīng)典的案例來(lái)剖析面向?qū)ο缶幊痰闹R(shí),同時(shí)也通過(guò)這些案例為大家講解如何運(yùn)用之前學(xué)過(guò)的Python知識(shí)。

撲克游戲。

說(shuō)明:簡(jiǎn)單起見(jiàn),我們的撲克只有52張牌(沒(méi)有大小王),游戲需要將52張牌發(fā)到4個(gè)玩家的手上,每個(gè)玩家手上有13張牌,按照黑桃、紅心、草花、方塊的順序和點(diǎn)數(shù)從小到大排列,暫時(shí)不實(shí)現(xiàn)其他的功能。

使用面向?qū)ο缶幊谭椒ǎ紫刃枰獜膯?wèn)題的需求中找到對(duì)象并抽象出對(duì)應(yīng)的類(lèi),此外還要找到對(duì)象的屬性和行為。當(dāng)然,這件事情并不是特別困難,我們可以從需求的描述中找出名詞和動(dòng)詞,名詞通常就是對(duì)象或者是對(duì)象的屬性,而動(dòng)詞通常是對(duì)象的行為。撲克游戲中至少應(yīng)該有三類(lèi)對(duì)象,分別是牌、撲克和玩家,牌、撲克、玩家三個(gè)類(lèi)也并不是孤立的。類(lèi)和類(lèi)之間的關(guān)系可以粗略的分為is-a關(guān)系(繼承)、has-a關(guān)系(關(guān)聯(lián))和use-a關(guān)系(依賴(lài))。很顯然撲克和牌是has-a關(guān)系,因?yàn)橐桓睋淇擞校╤as-a)52張牌;玩家和牌之間不僅有關(guān)聯(lián)關(guān)系還有依賴(lài)關(guān)系,因?yàn)橥婕沂稚嫌校╤as-a)牌而且玩家使用了(use-a)牌。

牌的屬性顯而易見(jiàn),有花色和點(diǎn)數(shù)。我們可以用0到3的四個(gè)數(shù)字來(lái)代表四種不同的花色,但是這樣的代碼可讀性會(huì)非常糟糕,因?yàn)槲覀儾⒉恢篮谔?、紅心、草花、方塊跟0到3的數(shù)字的對(duì)應(yīng)關(guān)系。如果一個(gè)變量的取值只有有限多個(gè)選項(xiàng),我們可以使用枚舉。與C、Java等語(yǔ)言不同的是,Python中沒(méi)有聲明枚舉類(lèi)型的關(guān)鍵字,但是可以通過(guò)繼承enum模塊的Enum類(lèi)來(lái)創(chuàng)建枚舉類(lèi)型,代碼如下所示。

from enum import Enum
class Suite(Enum):
    """花色(枚舉)"""
    SPADE, HEART, CLUB, DIAMOND = range(4)

通過(guò)上面的代碼可以看出,定義枚舉類(lèi)型其實(shí)就是定義符號(hào)常量,如SPADE、HEART等。每個(gè)符號(hào)常量都有與之對(duì)應(yīng)的值,這樣表示黑桃就可以不用數(shù)字0,而是用Suite.SPADE;同理,表示方塊可以不用數(shù)字3, 而是用Suite.DIAMOND。注意,使用符號(hào)常量肯定是優(yōu)于使用字面常量的,因?yàn)槟軌蜃x懂英文就能理解符號(hào)常量的含義,代碼的可讀性會(huì)提升很多。Python中的枚舉類(lèi)型是可迭代類(lèi)型,簡(jiǎn)單的說(shuō)就是可以將枚舉類(lèi)型放到for-in循環(huán)中,依次取出每一個(gè)符號(hào)常量及其對(duì)應(yīng)的值,如下所示。

for suite in Suite:
    print(f'{suite}: {suite.value}')

接下來(lái)我們可以定義牌類(lèi)。

class Card:
    """牌"""
    def __init__(self, suite, face):
        self.suite = suite
        self.face = face
    def __repr__(self):
        suites = '????'
        faces = ['', 'A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K']
        # 根據(jù)牌的花色和點(diǎn)數(shù)取到對(duì)應(yīng)的字符
        return f'{suites[self.suite.value]}{faces[self.face]}'

可以通過(guò)下面的代碼來(lái)測(cè)試下Card類(lèi)。

card1 = Card(Suite.SPADE, 5)
card2 = Card(Suite.HEART, 13)
print(card1, card2)    # ?5 ?K

接下來(lái)我們定義撲克類(lèi)。

import random
class Poker:
    """撲克"""
    def __init__(self):
        # 通過(guò)列表的生成式語(yǔ)法創(chuàng)建一個(gè)裝52張牌的列表
        self.cards = [Card(suite, face) for suite in Suite
                      for face in range(1, 14)]
        # current屬性表示發(fā)牌的位置
        self.current = 0
    def shuffle(self):
        """洗牌"""
        self.current = 0
        # 通過(guò)random模塊的shuffle函數(shù)實(shí)現(xiàn)列表的隨機(jī)亂序
        random.shuffle(self.cards)
    def deal(self):
        """發(fā)牌"""
        card = self.cards[self.current]
        self.current += 1
        return card
    @property
    def has_next(self):
        """還有沒(méi)有牌可以發(fā)"""
        return self.current < len(self.cards)

可以通過(guò)下面的代碼來(lái)測(cè)試下Poker類(lèi)。

poker = Poker()
poker.shuffle()
print(poker.cards)

定義玩家類(lèi)。

class Player:
    """玩家"""
    def __init__(self, name):
        self.name = name
        self.cards = []
    def get_one(self, card):
        """摸牌"""
        self.cards.append(card)
    def arrange(self):
        self.cards.sort()

創(chuàng)建四個(gè)玩家并將牌發(fā)到玩家的手上。

poker = Poker()
poker.shuffle()
players = [Player('東邪'), Player('西毒'), Player('南帝'), Player('北丐')]
for _ in range(13):
    for player in players:
        player.get_one(poker.deal())
for player in players:
    player.arrange()
    print(f'{player.name}: ', end='')
    print(player.cards)

執(zhí)行上面的代碼會(huì)在player.arrange()那里出現(xiàn)異常,因?yàn)?code>Player的arrange方法使用了列表的sort對(duì)玩家手上的牌進(jìn)行排序,排序需要比較兩個(gè)Card對(duì)象的大小,而<運(yùn)算符又不能直接作用于Card類(lèi)型,所以就出現(xiàn)了TypeError異常,異常消息為:'<' not supported between instances of 'Card' and 'Card'。

為了解決這個(gè)問(wèn)題,我們可以對(duì)Card類(lèi)的代碼稍作修改,使得兩個(gè)Card對(duì)象可以直接用<進(jìn)行大小的比較。這里用到技術(shù)叫運(yùn)算符重載,Python中要實(shí)現(xiàn)對(duì)<運(yùn)算符的重載,需要在類(lèi)中添加一個(gè)名為__lt__的魔術(shù)方法。很顯然,魔術(shù)方法__lt__中的lt是英文單詞“less than”的縮寫(xiě),以此類(lèi)推,魔術(shù)方法__gt__對(duì)應(yīng)>運(yùn)算符,魔術(shù)方法__le__對(duì)應(yīng)<=運(yùn)算符,__ge__對(duì)應(yīng)>=運(yùn)算符,__eq__對(duì)應(yīng)==運(yùn)算符,__ne__對(duì)應(yīng)!=運(yùn)算符。

修改后的Card類(lèi)代碼如下所示。

class Card:
    """牌"""
    def __init__(self, suite, face):
        self.suite = suite
        self.face = face
    def __repr__(self):
        suites = '????'
        faces = ['', 'A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K']
        # 根據(jù)牌的花色和點(diǎn)數(shù)取到對(duì)應(yīng)的字符
        return f'{suites[self.suite.value]}{faces[self.face]}'
    def __lt__(self, other):
        # 花色相同比較點(diǎn)數(shù)的大小
        if self.suite == other.suite:
            return self.face < other.face
        # 花色不同比較花色對(duì)應(yīng)的值
        return self.suite.value < other.suite.value

說(shuō)明: 大家可以嘗試在上面代碼的基礎(chǔ)上寫(xiě)一個(gè)簡(jiǎn)單的撲克游戲,如21點(diǎn)游戲(Black Jack),游戲的規(guī)則可以自己在網(wǎng)上找一找。

工資結(jié)算系統(tǒng)。

要求:某公司有三種類(lèi)型的員工,分別是部門(mén)經(jīng)理、程序員和銷(xiāo)售員。需要設(shè)計(jì)一個(gè)工資結(jié)算系統(tǒng),根據(jù)提供的員工信息來(lái)計(jì)算員工的月薪。其中,部門(mén)經(jīng)理的月薪是固定15000元;程序員按工作時(shí)間(以小時(shí)為單位)支付月薪,每小時(shí)200元;銷(xiāo)售員的月薪由1800元底薪加上銷(xiāo)售額5%的提成兩部分構(gòu)成。

通過(guò)對(duì)上述需求的分析,可以看出部門(mén)經(jīng)理、程序員、銷(xiāo)售員都是員工,有相同的屬性和行為,那么我們可以先設(shè)計(jì)一個(gè)名為Employee的父類(lèi),再通過(guò)繼承的方式從這個(gè)父類(lèi)派生出部門(mén)經(jīng)理、程序員和銷(xiāo)售員三個(gè)子類(lèi)。很顯然,后續(xù)的代碼不會(huì)創(chuàng)建Employee 類(lèi)的對(duì)象,因?yàn)槲覀冃枰氖蔷唧w的員工對(duì)象,所以這個(gè)類(lèi)可以設(shè)計(jì)成專(zhuān)門(mén)用于繼承的抽象類(lèi)。Python中沒(méi)有定義抽象類(lèi)的關(guān)鍵字,但是可以通過(guò)abc模塊中名為ABCMeta 的元類(lèi)來(lái)定義抽象類(lèi)。關(guān)于元類(lèi)的知識(shí),后面的課程中會(huì)有專(zhuān)門(mén)的講解,這里不用太糾結(jié)這個(gè)概念,記住用法即可。

from abc import ABCMeta, abstractmethod
class Employee(metaclass=ABCMeta):
    """員工"""
    def __init__(self, name):
        self.name = name
    @abstractmethod
    def get_salary(self):
        """結(jié)算月薪"""
        pass

在上面的員工類(lèi)中,有一個(gè)名為get_salary的方法用于結(jié)算月薪,但是由于還沒(méi)有確定是哪一類(lèi)員工,所以結(jié)算月薪雖然是員工的公共行為但這里卻沒(méi)有辦法實(shí)現(xiàn)。對(duì)于暫時(shí)無(wú)法實(shí)現(xiàn)的方法,我們可以使用abstractmethod裝飾器將其聲明為抽象方法,所謂抽象方法就是只有聲明沒(méi)有實(shí)現(xiàn)的方法,聲明這個(gè)方法是為了讓子類(lèi)去重寫(xiě)這個(gè)方法。接下來(lái)的代碼展示了如何從員工類(lèi)派生出部門(mén)經(jīng)理、程序員、銷(xiāo)售員這三個(gè)子類(lèi)以及子類(lèi)如何重寫(xiě)父類(lèi)的抽象方法。

class Manager(Employee):
    """部門(mén)經(jīng)理"""
    def get_salary(self):
        return 15000.0
class Programmer(Employee):
    """程序員"""
    def __init__(self, name, working_hour=0):
        super().__init__(name)
        self.working_hour = working_hour
    def get_salary(self):
        return 200 * self.working_hour
class Salesman(Employee):
    """銷(xiāo)售員"""
    def __init__(self, name, sales=0):
        super().__init__(name)
        self.sales = sales
    def get_salary(self):
        return 1800 + self.sales * 0.05

上面的Manager、Programmer、Salesman三個(gè)類(lèi)都繼承自Employee,三個(gè)類(lèi)都分別重寫(xiě)了get_salary方法。重寫(xiě)就是子類(lèi)對(duì)父類(lèi)已有的方法重新做出實(shí)現(xiàn)。相信大家已經(jīng)注意到了,三個(gè)子類(lèi)中的get_salary各不相同,所以這個(gè)方法在程序運(yùn)行時(shí)會(huì)產(chǎn)生多態(tài)行為,多態(tài)簡(jiǎn)單的說(shuō)就是調(diào)用相同的方法,不同的子類(lèi)對(duì)象做不同的事情。

我們通過(guò)下面的代碼來(lái)完成這個(gè)工資結(jié)算系統(tǒng),由于程序員和銷(xiāo)售員需要分別錄入本月的工作時(shí)間和銷(xiāo)售額,所以在下面的代碼中我們使用了Python內(nèi)置的isinstance函數(shù)來(lái)判斷員工對(duì)象的類(lèi)型。我們之前講過(guò)的type函數(shù)也能識(shí)別對(duì)象的類(lèi)型,但是isinstance函數(shù)更加強(qiáng)大,因?yàn)樗梢耘袛喑鲆粋€(gè)對(duì)象是不是某個(gè)繼承結(jié)構(gòu)下的子類(lèi)型,你可以簡(jiǎn)答的理解為type函數(shù)是對(duì)對(duì)象類(lèi)型的精準(zhǔn)匹配,而isinstance函數(shù)是對(duì)對(duì)象類(lèi)型的模糊匹配。

emps = [
    Manager('劉備'), Programmer('諸葛亮'), Manager('曹操'), 
    Programmer('荀彧'), Salesman('呂布'), Programmer('張遼'),
]
for emp in emps:
    if isinstance(emp, Programmer):
        emp.working_hour = int(input(f'請(qǐng)輸入{emp.name}本月工作時(shí)間: '))
    elif isinstance(emp, Salesman):
        emp.sales = float(input(f'請(qǐng)輸入{emp.name}本月銷(xiāo)售額: '))
    print(f'{emp.name}本月工資為: ¥{emp.get_salary():.2f}元')

總結(jié)

面向?qū)ο蟮木幊趟枷敕浅5暮?,也符合人?lèi)的正常思維習(xí)慣,但是要想靈活運(yùn)用面向?qū)ο缶幊讨械某橄?、封裝、繼承、多態(tài)需要長(zhǎng)時(shí)間的積累和沉淀,這件事情無(wú)法一蹴而就,屬于“路漫漫其修遠(yuǎn)兮,吾將上下而求索”的東西。

到此這篇關(guān)于Python超細(xì)致探究面向?qū)ο蟮奈恼戮徒榻B到這了,更多相關(guān)Python 面向?qū)ο髢?nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Python CSV文件模塊的使用案例分析

    Python CSV文件模塊的使用案例分析

    這篇文章主要介紹了Python CSV文件模塊的使用,結(jié)合具體案例形式分析了Python使用csv模塊操作csv文件的相關(guān)使用技巧與相關(guān)注意事項(xiàng),需要的朋友可以參考下
    2019-12-12
  • Python實(shí)現(xiàn)的HTTP并發(fā)測(cè)試完整示例

    Python實(shí)現(xiàn)的HTTP并發(fā)測(cè)試完整示例

    這篇文章主要介紹了Python實(shí)現(xiàn)的HTTP并發(fā)測(cè)試,涉及Python多線(xiàn)程并發(fā)操作相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2015-05-05
  • Python Flask-web表單使用詳解

    Python Flask-web表單使用詳解

    這篇文章主要為大家詳細(xì)介紹了Python Flask-web表單的使用方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-11-11
  • python接口自動(dòng)化測(cè)試數(shù)據(jù)和代碼分離解析

    python接口自動(dòng)化測(cè)試數(shù)據(jù)和代碼分離解析

    代碼的可維護(hù)性除了代碼冗余之外還有就是數(shù)據(jù)盡量不要和代碼摻雜在一起,因?yàn)殚喿x起來(lái)會(huì)非常的凌亂;數(shù)據(jù)分離能更好的增加代碼可讀性和可維護(hù)性,也能更好的二次修改使用
    2021-09-09
  • Python列表排序 list.sort方法和內(nèi)置函數(shù)sorted用法

    Python列表排序 list.sort方法和內(nèi)置函數(shù)sorted用法

    這篇文章主要介紹了Python列表排序 list.sort方法和內(nèi)置函數(shù)sorted用法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-03-03
  • 詳細(xì)分析Python可變對(duì)象和不可變對(duì)象

    詳細(xì)分析Python可變對(duì)象和不可變對(duì)象

    這篇文章主要介紹了Python可變對(duì)象和不可變對(duì)象的相關(guān)資料,文中講解非常細(xì)致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下
    2020-07-07
  • Python中使用pypdf2合并、分割、加密pdf文件的代碼詳解

    Python中使用pypdf2合并、分割、加密pdf文件的代碼詳解

    這篇文章主要介紹了Python中使用pypdf2合并、分割、加密pdf文件的代碼,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-05-05
  • Python利用matplotlib實(shí)現(xiàn)動(dòng)態(tài)可視化詳解

    Python利用matplotlib實(shí)現(xiàn)動(dòng)態(tài)可視化詳解

    Python中的數(shù)據(jù)可視化是指原始數(shù)據(jù)的圖形表示,以更好地可視化、理解和推理,Python提供了各種庫(kù),包含用于可視化數(shù)據(jù)的不同特性,下面我們就來(lái)看看如何利用matplotlib實(shí)現(xiàn)動(dòng)態(tài)可視化吧
    2023-08-08
  • Python爬豆瓣電影實(shí)例

    Python爬豆瓣電影實(shí)例

    本篇文章給大家通過(guò)Python爬豆瓣電影實(shí)例對(duì)Python爬蟲(chóng)更深入的講解,有興趣的學(xué)習(xí)下。
    2018-02-02
  • python中列表(list)和元組(tuple)的深入講解

    python中列表(list)和元組(tuple)的深入講解

    這篇文章主要給大家介紹了關(guān)于python中列表(list)和元組(tuple)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03

最新評(píng)論

泰兴市| 镇赉县| 达日县| 米易县| 伊宁县| 怀来县| 青浦区| 阿勒泰市| 深圳市| 搜索| 虹口区| 南通市| 即墨市| 蕲春县| 曲靖市| 刚察县| 元朗区| 浦东新区| 平和县| 长海县| 繁峙县| 商南县| 房山区| 马尔康县| 新化县| 乐昌市| 平邑县| 林西县| 莎车县| 施秉县| 克山县| 长阳| 连州市| 武平县| 勐海县| 赣州市| 探索| 淮滨县| 库伦旗| 宜春市| 雅江县|