Python-十一、類與對象

1您机、明確項目目標

類與對象的兩用用法

1.1穿肄、類作為函數(shù)包

使用類把函數(shù)打包封裝在一起年局。

1.2、類作為對象的模板

使用類生成實例對象咸产。

游戲中的“屬性克制”:
在游戲中定義三種類型的角色:圣光騎士矢否、暗影刺客、精靈弩手脑溢,他們三者之間也會互相克制僵朗。

2、分析過程屑彻,拆解項目

首先验庙,回顧之前我們做過的這個游戲的功能:
版本1.0:將項目1的部分代碼,調整后用函數(shù)封裝并調用社牲。
版本2.0:從角色池里為雙方隨機選出3個角色粪薛,并隨機生成血量和攻擊值。
版本3.0:詢問玩家角色出場順序搏恤,并打印出來
版本4.0:根據(jù)出場順序和對方進行三輪PK违寿,并輸出戰(zhàn)果

現(xiàn)在我們要升級以前的版本了挑社,咱們怎么搞陨界?當然是先拆版本啦:
版本1.0:類的封裝,將類作為函數(shù)包痛阻,把各種函數(shù)打包起來菌瘪。
版本2.0:類的繼承和實例化,讓三種不同的角色的屬性不同阱当。
版本1.0:為三個角色的類添加一個讓角色之間可以相互克制的類方法俏扩。

拆分邏輯可以繼續(xù)細拆為:
版本1.0:我們知道類能夠作為函數(shù)包來使用,而上次的程序中有特別多函數(shù)弊添,所以我們可以先用類把他們打包到一起录淡,做成一個“游戲運行”類。打包完畢后油坝,我們再微調一些代碼嫉戚,為實現(xiàn)新功能做好預先準備。
版本2.0:接下來我們需要為游戲創(chuàng)建3種角色澈圈。因為類是實例對象的模版彬檀,所以我們可以把三種角色封裝成三個屬性不同的類(騎士、刺客瞬女、弩手)窍帝。封裝完畢后,我們還需要這三種角色能在“游戲運行”類中被調用诽偷。
版本3.0:最后一步就是要讓角色之間可以相互克制坤学。想做到這件事疯坤,最簡單的方式是在剛才寫的三個角色的類中,每個類添加一個“屬性克制”的類方法深浮。

3压怠、逐步執(zhí)行,代碼實現(xiàn)

先回顧老版本的代碼:

import time,random

# 需要的數(shù)據(jù)和變量放在開頭
player_list =  ['【狂血戰(zhàn)士】','【森林箭手】','【光明騎士】','【獨行劍客】','【格斗大師】','【槍彈專家】']
enemy_list = ['【暗黑戰(zhàn)士】','【黑暗弩手】','【暗夜騎士】','【嗜血刀客】','【首席刺客】','【陷阱之王】']
players = random.sample(player_list,3)  
enemies = random.sample(enemy_list,3)
player_info = {}
enemy_info = {}

# 隨機生成角色的屬性
def born_role():
    life = random.randint(100,180)
    attack = random.randint(30,50)
    return life,attack

# 生成和展示角色信息
def show_role():
    for i in range(3):
        player_info[players[i]] = born_role()
        enemy_info[enemies[i]] = born_role()
    
    # 展示我方的3個角色
    print('----------------- 角色信息 -----------------')
    print('你的人物:')
    for i in range(3):
        print('%s  血量:%s  攻擊:%s' 
        %(players[i],player_info[players[i]][0],player_info[players[i]][1]))
    print('--------------------------------------------')
    print('電腦敵人:')

    # 展示敵方的3個角色
    for i in range(3):
        print('%s  血量:%s  攻擊:%s' 
        %(enemies[i],enemy_info[enemies[i]][0],enemy_info[enemies[i]][1]))
    print('--------------------------------------------')
    input('請按回車鍵繼續(xù)飞苇。\n')  # 為了讓玩家更有控制感刑峡,可以插入類似的代碼來切分游戲進程。

# 角色排序玄柠,選擇出場順序。
def order_role(): 
    global players
    order_dict = {}
    for i in range(3):
        order = int(input('你想將 %s 放在第幾個上場诫舅?(輸入數(shù)字1~3)'% players[i]))
        order_dict[order] = players[i]  

    players = []
    for i in range(1,4):
        players.append(order_dict[i]) 
    
    print('\n我方角色的出場順序是:%s羽利、%s、%s' %(players[0],players[1],players[2]))
    print('敵方角色的出場順序是:%s刊懈、%s这弧、%s' %(enemies[0],enemies[1],enemies[2]))

# 角色PK
def pk_role(): 
    round = 1  
    score = 0
    for i in range(3):  # 一共要打三局
        player_name = players[i]  
        enemy_name = enemies[i] 
        player_life = player_info[players[i]][0]
        player_attack = player_info[players[i]][1]
        enemy_life = enemy_info[enemies[i]][0]
        enemy_attack = enemy_info[enemies[i]][1]

        # 每一局開戰(zhàn)前展示戰(zhàn)斗信息
        print('\n----------------- 【第%s局】 -----------------' % round)
        print('玩家角色:%s vs 敵方角色:%s ' %(player_name,enemy_name))
        print('%s 血量:%s  攻擊:%s' %(player_name,player_life,player_attack))
        print('%s 血量:%s  攻擊:%s' %(enemy_name,enemy_life,enemy_attack))
        print('--------------------------------------------')
        input('請按回車鍵繼續(xù)。\n')

        # 開始判斷血量是否都大于零虚汛,然后互扣血量匾浪。
        while player_life > 0 and enemy_life > 0:
            enemy_life = enemy_life - player_attack
            player_life = player_life - enemy_attack
            print('%s發(fā)起了攻擊,%s剩余血量%s' % (player_name,enemy_name,enemy_life))
            print('%s發(fā)起了攻擊卷哩,%s剩余血量%s' % (enemy_name,player_name,player_life))
            print('--------------------------------------------')
            time.sleep(1)
        else:  # 每局的戰(zhàn)果展示蛋辈,以及分數(shù)score和局數(shù)的變化。
            # 調用show_result()函數(shù)将谊,打印返回元組中的result冷溶。
            print(show_result(player_life,enemy_life)[1])
            # 調用show_result()函數(shù),完成計分變動尊浓。
            score += int(show_result(player_life,enemy_life)[0])
            round += 1
    input('\n點擊回車逞频,查看比賽的最終結果\n')

    if score > 0:
        print('【最終結果:你贏了!】\n')
    elif score < 0:
        print('【最終結果:你輸了栋齿!】\n')
    else:
        print('【最終結果:平局苗胀!】\n')

# 返回單局戰(zhàn)果和計分法所加分數(shù)。
def show_result(player_life,enemy_life):  # 注意:該函數(shù)要設定參數(shù)瓦堵,才能判斷單局戰(zhàn)果基协。
    if player_life > 0 and enemy_life <= 0:
        result = '\n敵人死翹翹了,你贏了谷丸!'
        return 1,result  # 返回元組(1,'\n敵人死翹翹了堡掏,你贏了!')刨疼,類似角色屬性的傳遞泉唁。
    elif player_life <= 0 and enemy_life > 0:        
        result = '\n悲催鹅龄,敵人把你干掉了!'
        return -1,result
    else :
        result = '\n哎呀亭畜,你和敵人同歸于盡了扮休!'
        return 0,result

# (主函數(shù))展開戰(zhàn)斗流程
def main():
    show_role()  # 生成和展示角色信息
    order_role()  # 角色排序,選擇出場順序
    pk_role()  # 完成角色PK拴鸵,并展示PK結果

# 啟動程序(即調用主函數(shù))
main()

然后用類的形式玷坠,把函數(shù)整理好,實例化類劲藐,轉化為新版本

在新版本中八堡,加入了克制系統(tǒng)。

實現(xiàn)方法是通過增加一段BUFF的判斷聘芜,就是當A的對手為B時兄渺,把A的攻擊力提高50%。

import random
import time

# 創(chuàng)建一個類汰现,可實例化成具體的游戲角色
class Role:
    def __init__(self, name='【角色】'):  # 把角色名作為默認參數(shù)
        self.name = name
        self.life = random.randint(100,150)
        self.attack = random.randint(30,50)

# 創(chuàng)建3個子類挂谍,可實例化為3個不同的職業(yè)

class Knight(Role):
    def __init__(self, name='【圣光騎士】'):   # 把子類角色名作為默認參數(shù)
        Role.__init__(self,name)  # 利用了父類的初始化函數(shù)
        self.life = self.life*5  # 騎士有5份血量
        self.attack = self.attack*3    # 騎士有3份攻擊力

    # 職業(yè)克制關系
    def fight_buff(self, opponent,str1,str2):
        if opponent.name  == '【暗影刺客】':
            self.attack = int(self.attack * 1.5)
            print('『%s』【圣光騎士】對 『%s』【暗影刺客】說:“讓無盡光芒制裁你的墮落!”'%(str1, str2))

class Assassin(Role):
    def __init__(self, name='【暗影刺客】'):
        Role.__init__(self,name)
        self.life = self.life*3
        self.attack = self.attack*5

    # 職業(yè)克制關系
    def fight_buff(self, opponent,str1,str2):
        if opponent.name  == '【精靈弩手】':
            self.attack = int(self.attack * 1.5)
            print('『%s』【暗影刺客】對 『%s』【精靈弩手】說:“主動找死瞎饲,就別怪我心狠手辣口叙。”'%(str1, str2)) 

class Bowman(Role):
    def __init__(self, name='【精靈弩手】'):
        Role.__init__(self,name)
        self.life = self.life*4
        self.attack = self.attack*4

    # 職業(yè)克制關系
    def fight_buff(self, opponent,str1,str2):
        if opponent.name  == '【圣光騎士】':
            self.attack = int(self.attack * 1.5)
            print('『%s』【精靈弩手】對 『%s』【圣光騎士】說:“騎著倔驢又如何嗅战?你都碰不到我衣服妄田。”'%(str1, str2))

# 創(chuàng)建一個類驮捍,可生成3V3并展示:可分為:歡迎語→隨機生成→展示角色
class Game():
    def __init__(self):
        self.players = []  # 存玩家順序
        self.enemies = []  # 存敵人順序
        self.score = 0  # 比賽積分
        self.i = 0  # 記輪次
        # 依次執(zhí)行以下函數(shù)
        self.game_start()  # 歡迎語
        self.born_role()  # 隨機生成6個角色
        self.show_role()  # 展示角色
        self.order_role()  # 排序并展示
        self.pk_role()  # 讓雙方 Pk 并展示結果
        self.show_result()  # 展示最終結局

    # 歡迎語
    def game_start(self):
        print('------------ 歡迎來到“煉獄角斗場” ------------')
        print('在昔日的黃昏山脈形庭,奧盧帝國的北境邊界上,有傳說中的“煉獄角斗場”厌漂。')
        print('鮮血與戰(zhàn)斗是角斗士的歸宿萨醒,金錢與榮耀是角斗士的信仰!')
        print('今日苇倡,只要你【你的隊伍】能取得勝利富纸,你將獲得一筆夠花500年的財富。')
        time.sleep(2)
        print('將隨機生成【你的隊伍】和【敵人隊伍】旨椒!')
        input('\n狹路相逢勇者勝晓褪,請按任意鍵繼續(xù)。\n')
    
    # 隨機生成6個角色
    def born_role(self):
        for i in range(3):
            self.players.append(random.choice([Knight(),Assassin(),Bowman()]))
            self.enemies.append(random.choice([Knight(),Assassin(),Bowman()]))

    # 展示角色
    def show_role(self):
        print('----------------- 角色信息 -----------------')
        print('你的隊伍:')
        for i in range(3):
            print( '『我方』%s 血量:%s  攻擊:%s'%
            (self.players[i].name,self.players[i].life,self.players[i].attack))
        print('--------------------------------------------')

        print('敵人隊伍:')
        for i in range(3):
            print('『敵方』%s 血量:%s  攻擊:%s'%
            (self.enemies[i].name,self.enemies[i].life,self.enemies[i].attack))
        print('--------------------------------------------')
        input('請按回車鍵繼續(xù)综慎。\n')

    # 排序并展示
    def order_role(self):
        order_dict = {}
        for i in range(3):
            order = int(input('你想將 %s 放在第幾個上場涣仿?(輸入數(shù)字1~3)'% self.players[i].name))
            order_dict[order] = self.players[i]
        self.players = []
        for i in range(1,4):
            self.players.append(order_dict[i]) 
        print('\n你的隊伍出場順序是:%s、%s、%s'
        %(self.players[0].name,self.players[1].name,self.players[2].name))
        print('敵人隊伍出場順序是:%s好港、%s榔袋、%s'
        %(self.enemies[0].name,self.enemies[1].name,self.enemies[2].name))


    # 讓雙方 Pk 并展示結果
    def pk_role(self):
        for i in range(3):
            print('\n----------------- 【第%s輪】 -----------------' % (i+1))
            # 每一局開戰(zhàn)前加buff
            self.players[i].fight_buff(self.enemies[i],'我方','敵方')
            self.enemies[i].fight_buff(self.players[i],'敵方','我方')
            input('\n戰(zhàn)斗雙方準備完畢婆芦,請按回車鍵繼續(xù)。')
            print('--------------------------------------------')
    
            while self.players[i].life >0 and self.enemies[i].life>0:
                self.enemies[i].life -= self.players[i].attack
                self.players[i].life -= self.enemies[i].attack
                print('我方%s 發(fā)起了攻擊,敵方%s 剩余血量 %s'%
                (self.players[i].name,self.enemies[i].name,self.enemies[i].life))
                print('敵方%s 發(fā)起了攻擊播急,我方%s 剩余血量 %s'%
                (self.enemies[i].name,self.players[i].name,self.players[i].life))
                print('--------------------------------------------')
                time.sleep(1)
            if self.players[i].life <= 0 and self.enemies[i].life> 0:
                print('\n很遺憾勺阐,我方%s 掛掉了鳖敷!'% (self.players[i].name))
                self.score -= 1
            elif self.players[i].life >0 and self.enemies[i].life<= 0: 
                print('\n恭喜匿又,我方%s 活下來了。'% (self.players[i].name))
                self.score += 1
            else:
                print('\n我的天塘秦,他們倆都死了八显ā!')

    # 展示最終結局
    def show_result(self):
        input('\n請按回車查看最終結果尊剔。\n')
        if self.score >0:
            print('【最終結果】\n你贏了精偿,最終的財寶都歸你了!')
        elif self.score == 0:
            print('【最終結果】\n你沒有勝利赋兵,但也沒有失敗,在夜色中灰溜溜離開了奧盧帝國搔预。')
        else:
            print('【最終結果】\n你輸了霹期。煉獄角斗場又多了幾具枯骨。')

game = Game()

4拯田、練習題历造、那個人來了

練習目標:

這個練習,會訓練運用“子類的繼承和定制”相關知識船庇。

練習要求:

在練習中吭产,需要通過代碼的運行結果和所學知識,補全代碼鸭轮。
在補全代碼的過程中臣淤,需要對子類的繼承和定制有清晰的認知。

# 實現(xiàn)效果
大家注意了窃爷!
一個叫“吉多”的人來了邑蒋。
大家注意了!
一個叫“范羅蘇姆”的男人來了按厘。
大家注意了医吊!
那個叫“范羅蘇姆”的男人留下了他的背影。
# 補全代碼:

class Person:
    def __init__(self, name):
        self.Person = name
        print('大家注意了 !')
    
    def show(self):
        print('一個叫“%s”的人來了逮京。' % (self.Person))

# 子類的繼承和定制
class Man(Person):

    def __init__(self):
        self.Person = '范羅蘇姆'
        print('大家注意了 !')
    
    def show(self):
        print('一個叫“%s”的男人來了卿堂。' % (self.Person))

    def leave(self):
        print('那個叫“%s”的男人留下了他的背影。' % (self.Person))

author1 = Person('吉多')
author1.show()
# author1.leave()  # 補全代碼后懒棉,運行該行會報錯:AttributeError:'Person' object has no attribute 'leave'.
author2 = Man()
author2.show()
author3 = Man()
author3.leave()

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末草描,一起剝皮案震驚了整個濱河市览绿,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌陶珠,老刑警劉巖挟裂,帶你破解...
    沈念sama閱讀 206,482評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異揍诽,居然都是意外死亡诀蓉,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,377評論 2 382
  • 文/潘曉璐 我一進店門暑脆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來渠啤,“玉大人,你說我怎么就攤上這事添吗×げ埽” “怎么了?”我有些...
    開封第一講書人閱讀 152,762評論 0 342
  • 文/不壞的土叔 我叫張陵碟联,是天一觀的道長妓美。 經常有香客問我,道長鲤孵,這世上最難降的妖魔是什么壶栋? 我笑而不...
    開封第一講書人閱讀 55,273評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮普监,結果婚禮上贵试,老公的妹妹穿的比我還像新娘。我一直安慰自己凯正,他們只是感情好毙玻,可當我...
    茶點故事閱讀 64,289評論 5 373
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著廊散,像睡著了一般桑滩。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上允睹,一...
    開封第一講書人閱讀 49,046評論 1 285
  • 那天施符,我揣著相機與錄音,去河邊找鬼擂找。 笑死戳吝,一個胖子當著我的面吹牛,可吹牛的內容都是我干的贯涎。 我是一名探鬼主播听哭,決...
    沈念sama閱讀 38,351評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了陆盘?” 一聲冷哼從身側響起普筹,我...
    開封第一講書人閱讀 36,988評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎隘马,沒想到半個月后太防,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 43,476評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡酸员,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 35,948評論 2 324
  • 正文 我和宋清朗相戀三年蜒车,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片幔嗦。...
    茶點故事閱讀 38,064評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡酿愧,死狀恐怖,靈堂內的尸體忽然破棺而出邀泉,到底是詐尸還是另有隱情嬉挡,我是刑警寧澤,帶...
    沈念sama閱讀 33,712評論 4 323
  • 正文 年R本政府宣布汇恤,位于F島的核電站庞钢,受9級特大地震影響,放射性物質發(fā)生泄漏因谎。R本人自食惡果不足惜基括,卻給世界環(huán)境...
    茶點故事閱讀 39,261評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蓝角。 院中可真熱鬧,春花似錦饭冬、人聲如沸使鹅。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,264評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽患朱。三九已至,卻和暖如春炊苫,著一層夾襖步出監(jiān)牢的瞬間裁厅,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,486評論 1 262
  • 我被黑心中介騙來泰國打工侨艾, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留执虹,地道東北人。 一個月前我還...
    沈念sama閱讀 45,511評論 2 354
  • 正文 我出身青樓唠梨,卻偏偏與公主長得像袋励,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,802評論 2 345

推薦閱讀更多精彩內容

  • 這是16年5月份編輯的一份比較雜亂適合自己觀看的學習記錄文檔茬故,今天18年5月份再次想寫文章盖灸,發(fā)現(xiàn)簡書還為我保存起的...
    Jenaral閱讀 2,732評論 2 9
  • 面向對象編程(OOP) 在前面的章節(jié)中赁炎,我們學習了Kotlin的語言基礎知識、類型系統(tǒng)钾腺、集合類以及泛型相關的知識徙垫。...
    Tenderness4閱讀 4,419評論 1 6
  • 面向對象介紹 范式編程 編程是程序員用 特定的語法+數(shù)據(jù)結構+算法 組成的代碼來告訴計算機如何執(zhí)行任務的過程。 一...
    drfung閱讀 1,901評論 0 1
  • 截止今天為止逗抑,雙十一所有的快遞已全部收到。雙十一之前寒亥,我還對自己說邮府,今年好像沒什么要買的。但是第二天一起床溉奕,...
    Sarah1989閱讀 313評論 3 9
  • 有人的地方褂傀,就有球場,人來人去加勤,乃風云際會之所仙辟。 1 秋色冷并刀。 天空卷積著烏云鳄梅,卻一點風也沒有叠国,夏蟬還在不知疲...
    美少女壯士_c902閱讀 117評論 0 0