python面向对象基础-01
面向對象(OOP)基本概念
前言
話說三國時期曹軍于官渡大敗袁紹,酒席之間,曹操詩興大發,吟道:喝酒唱歌,人生真爽! 眾將直呼:"丞相好詩",于是命印刷工匠刻板印刷以流傳天下;待工匠刻板完成,交與曹操一看,曹操感覺不妥,說道:"喝酒唱歌,此話太俗,應改為'對酒當歌'較好",于是名工匠重新刻板,當時還沒有出現活字印刷術,如果樣板要改,只能重新刻板,工匠眼看連夜刻版之工,徹底白費,心中叫苦不迭。可也只得照辦。版樣再次出來請曹操過目,曹操細細一品,覺得還是不好,說”人生真爽太過直接,應該改問語才夠意境,因此應改為‘對酒當歌,人生幾何?’“,于是....在活字印刷術還沒出現之前,如果版樣有改動,只能重新雕刻。而且在印刷完成后,這個樣板就失去了它的價值,如果需要其他樣板只能重新雕刻。而活字印刷術的出現就大大改善了印刷技術。如上例”喝酒唱歌,人生真爽“,如果用活字印刷,只需要改四個字就可,其余工作都未白做。豈不快哉!!活字印刷也反應了OOP。當要改動時,只需要修改部分,此為 可維護;當這些字用完后,并非就完全沒有價值了,它完全可以在后來的印刷中重復使用,此乃 可復用;此詩若要加字,只需另刻字加入即可,這就是 可擴展;字的排列可以橫排,也可以豎排,此是 靈活性好。 曹操吟詩工匠刻錄的故事(轉載) # 上述案列反應了面向對象的優點,即可維護性高,擴展性強,復用性高! # 這些特點非常適用于用戶需求變化頻繁的互聯網應用程序,這是學習面向對象的重要原因 # 但是面向對象設計的程序需涉及類與對象,相應的復雜度會提高! # # 并非所有程序都需要較高的擴展性,例如系統內核,一旦編寫完成,基本不會再修改,使用面向過程來設計則更適用 小結面向對象
面向對象:?# 是一種編程思想,是前輩們總結的編程經驗,指導程序員如何編寫出更好的程序?
核心:?# 對象?
程序就是一系列對象的集合,程序員負責調度控制這些對象來交互著完成任務 在面向對象中程序員的角度發生了改變,從具體的操作者變成了指揮者。
強調:對象不是憑空產生的,需要我們自己設計
面向對象的優缺點
''' 優點:1.可擴展性高2.靈活性高3.重用性高缺點:1.程序的復雜度提高了2.無法準確預知結果 '''使用場景:?# 對擴展性要求較高的程序,通常是直接面向用戶的,例如qq 微信?
注意點:?# 不是所有的程序都要采用面向對象,要根據實際需求來選擇?
面向對象的兩大核心:?# 類與對象?
類
'''類即類型、類別,是一種 抽象概念是一系列具備相同特征和相同行為的對象的集合 '''對象
'''對象就是具體存在的某個事物,具備自己的特征和行為對象就是特征和技能的結合體 '''類和對象的關系
'''類包含一系列對象對象屬于某個類在現實中先有對象再有類,程序中先有類再有對象我們必須先告訴計算機這類的對象有什么特征有什么行為 '''結論:?# 在面向對象編程時,第一步需要考慮需要什么樣的對象,對象具備什么樣的特征和行為,從而根據這些信息總結出需要的類?
用面向對象思想編程
類的定義語法及類名書寫規范
class 類的名稱:# 類中的內容,描述屬性和技能# 描述屬性用變量# 描述行為用函數'''類名書寫規范:1.見名知意2.名稱是大駝峰式(駝峰就是單詞首字母大寫,大駝峰就是第一個字母大寫,小駝峰是第一個字母小寫)3.其他規范與變量大致相同 '''屬性
''' 屬性可以寫在類中 類中的屬性,是對象公共的也可以寫在對象中 對象中的屬性,每個對象獨特的(不一樣的)如果類和對象中存在同樣的屬性,先訪問對象,如果沒有再訪問類 '''屬性的增刪改查
''' 增加屬性對象變量名稱.屬性名稱 = 屬性值egon.male = 'male' 刪除屬性del 對象的變量名稱.屬性名稱del egon.male 修改屬性 對象.屬性 = 新的值 查看所有屬性,訪問的是對象的所有屬性對象.__dict__ --> dict 可以訪問調用者自身的名稱空間訪問他的類對象.__class__ 返回類 ''' class Student:'''這是Student類的注釋'''def __init__(self, name):self.name = nameclass TeachOfOldBoy:company = 'oldboy'def __init__(self, name):self.name = name# ---------- 對象新增、修改、查看、刪除屬性 ------------- xuzhaolong = Student('xzl') print(xuzhaolong.name) # 對象.屬性 --> 訪問對象的屬性 # xzl # print(xuzhaolong.age) # 訪問不存在的屬性會報錯'Student' object has no attribute 'age' xuzhaolong.age = 18 # 對象.屬性 = 值 --> 為對象添加新屬性 print(xuzhaolong.age) # 18 xuzhaolong.age = 28 # 對象.屬性 = 新值 --> 修改屬性的值(如果該對象已有此屬性) print(xuzhaolong.age) # 28 del xuzhaolong.age # 刪除對象的屬性 # print(xuzhaolong.age) # 會報錯,屬性已被刪除,類中(屬性的查找順序:對象-->父類-->...如果還有父類,其他父類...-->Object)沒有這個屬性,AttributeError: 'Student' object has no attribute 'age'print(TeachOfOldBoy.__dict__) # __dict__查看調用者的名稱空間里的名字 # {'__module__': '__main__', 'company': 'oldboy', '__init__': <function TeachOfOldBoy.__init__ at 0x0000026D1AC8A9D8>, '__dict__': <attribute '__dict__' of 'TeachOfOldBoy' objects>, '__weakref__': <attribute '__weakref__' of 'TeachOfOldBoy' objects>, '__doc__': None} print(xuzhaolong.__dict__) # {'name': 'xzl', 'age': 28}# ---------- __class__ 查看調用者所屬類型(python里類也是一種數據類型) ------------- print(TeachOfOldBoy.__class__) # __class__ 查看調用者所屬類 # <class 'type'> print(xuzhaolong.__class__) # <class '__main__.Student'># ---------- __doc__ 查看調用者的注釋 ------------- print(TeachOfOldBoy.__doc__) # __doc__ 查看調用者的注釋 # None print(Student.__doc__) # __doc__ 查看調用者所屬類的注釋 # # 這是Student類的注釋 # print(xuzhaolong.__doc__) # __doc__ 查看調用者所屬類的注釋 # # 這是Student類的注釋 # # ------------ 類中的屬性與對象 ----------------- egon = TeachOfOldBoy('egon') print(egon.company) # oldboy egon.company = 'OldBoy' print(egon.company) # 修改對象的繼承的屬性不影響類中的屬性 # OldBoy print(TeachOfOldBoy.company) # oldboy 代碼體現屬性的查找順序:?# 屬性的查找順序:先找自己的,再找類的,再父類。。。。一直往上找到object,再沒有就報錯?
對象初始化__inint__
''' __init__方法特點1.當實例化對象時,會自動執行__init__方法2.會自動將對象作為第一個參數傳入,對象參數名稱為self,self這個名字可以改,但不建議(一眼就知道是對象本身了)功能用戶給對象賦初始值 ''' # 初始化,不僅僅只是賦初值,還可以做一些其他操作,來保證對象的正常生成 '''之前十個老師,每個老師都要輸姓名年齡等,而屬性的值又不一樣,就不能直接定義成類的屬性每定義一個對象都要寫一次,很麻煩那么我們可以使用函數來簡化這個賦值操作class Cls: # 定義一個類passdef init(obj, kind, color, age): # 定義一個方法來簡化給對象添加(定制)屬性obj.kind = kind # 即 對象.屬性 = 值(變量的) --> 像什么? 給對象添加屬性嘛obj.color = colorobj.age = ageobj1 = Cls() # 實例化出一個對象init(obj1, "泰日天", '棕色', 2) # 通過調用 init 函數來給該對象添加屬性obj2 = Cls()init(obj2, "拆家犬", '黑白', 1)# 這樣子就有了兩個對象,且都已經有了各自的屬性了'''class Dog:def __init__(self, kind, color, age):# print(locals()) # {'age': 2, 'color': '棕色', 'kind': '泰日天', 'self': <__main__.Dog object at 0x000002985BE586D8>}self.kind = kindself.color = colorself.age = age# __init__ 函數不允許寫返回值(不能寫,只能返回None,寫return None 沒有意思) 規定如此'''不過在類里面直接寫這個 init 函數會更方便(python內部做了一些處理)如上,當實例化對象時,會自動執行這個 __init__ 方法會自動將調用這個類實例化的對象作為第一個參數傳入,對象參數名稱為self'''# 那么在實例化的時候就可以簡寫成這樣了,四行變兩行 teidi = Dog("泰日天", '棕色', 2) # print(teidi.__dict__) # {'kind': '泰日天', 'color': '棕色', 'age': 2} erha = Dog("拆家犬", '黑白', 1)''' 其實上面的寫法還可以有優化,那個__init__ 函數還可以寫得更簡潔一點(參數越多越明顯)def __init__(self, kind, color, age):lcs = locals()lcs.pop('self')self.__dict__.update(lcs)上面寫法中的locals()內置函數在 __init__ 函數中,可以獲取 __init__ 函數名稱空間里的那些名字,它是一個字典# print(locals()) # {'age': 2, 'color': '棕色', 'kind': '泰日天', 'self': <__main__.Dog object at 0x000002985BE586D8>}我們將其賦給一個中間字典接收,將多余的 self 鍵值對去掉,就是我們對象想要的屬性而對象.__dict__正好也是一個字典# print(teidi.__dict__) # {'kind': '泰日天', 'color': '棕色', 'age': 2}都是字典?字典的update()方法還記得嗎?將這個中間字典update()到對象的.__dict__ 中,即完成了對象的屬性添加self.__dict__.update(lcs) ''' __init__
備注:關于python內一些 __名字__ 這種屬性是什么情況,可以參考這篇博客哦(都說不重要,但總有我這樣的好奇寶寶嘛)~? Python常用內建方法:__init__,__new__,__class__的使用詳解
綁定方法與非綁定方法
對象的精髓所在就是將數據和處理數據的函數整合到一起了,這樣一來,拿到一個對象就同時拿到了需要處理的數據以及處理數據的函數
''' ******* 這一塊基礎概念是重點 ******* 對象綁定方法:self --> 默認傳入對象默認情況下,類中的方法都是對象綁定方法當使用對象調用時其特殊之處在于調用該函數時會自動傳入對象本身作為第一個參數當使用類名來調用時就是一個普通函數,有幾個參數就傳幾個參數類綁定方法:@classmethodcls(加上@classmethod裝飾后自己將self改為cls(class是關鍵字)) --> 默認傳入類給類的抽象方法,默認傳入類作為參數 特殊之處:不管用類還是對象調用,都會自動傳入類本身,作為第一個參數何時綁定給對象:當函數邏輯需要訪問對象中的數據時何時綁定給類:當函數邏輯需要訪問類中的數據時 非綁定方法:@staticmethod裝飾成普通函數,不管誰調都一樣既不需要訪問類的數據也不需要訪問對象的數據定義時有幾個參數調用時就需要傳入幾個參數''' class Dog:species = 'dog'# 初始化方法 __init__ 也屬于對象綁定方法def __init__(self, kind, nickname, skill):self.kind = kindself.nickname = nicknameself.skill = skill# 這就屬于一個對象綁定方法,默認將對象作為第一個參數傳入(調用的時候不需要手動傳入)def introduce(self):print(f"我是{self.kind},我能{self.skill},人送外號{self.nickname}")# 類綁定方法 @classmethoddef tell_species(cls): # 先寫裝飾器再寫函數,默認參數就是cls了,寫完函數再裝飾的話,記得把self換成cls,表示參數是一個類print(f"我的物種是{cls.species}")# 非綁定方法(既不需要傳入類,也不需要傳入對象) @staticmethoddef normal_func(arg1, arg2):print(f"參數一:{arg1} 參數二:{arg2},這只是一個普通方法啦~")taidi = Dog('泰迪', '泰日天', '日天') erha = Dog('二哈', '拆家犬', '拆家')# --------綁定對象方法的調用 taidi.introduce() erha.introduce() # 我是泰迪,我能日天,人送外號泰日天 # 我是二哈,我能拆家,人送外號拆家犬 Dog.introduce(erha) # 類調用對象的方法要手動把對象傳入進去 # 我是二哈,我能拆家,人送外號拆家犬# --------類綁定方法調用 Dog.tell_species() taidi.tell_species() # 可以直接調用,無需手動傳入 class # 我的物種是dog # 我的物種是dog# --------非綁定方法調用 Dog.normal_func(1, 2) # 非綁定方法,定義時有幾個參數,調用時就要傳幾個參數 taidi.normal_func(1, 2) # 非綁定方法,定義時有幾個參數,調用時就要傳幾個參數 # 參數一:1 參數二:2,這只是一個普通方法啦~ # 參數一:1 參數二:2,這只是一個普通方法啦~ 對象綁定方法、類綁定方法、非綁定方法利用pickle模塊將對象序列化到本地
如單機游戲的存檔(把對象的數據等信息存儲到文件中,下次啟動再讀取回來) --> 游戲擴展
import pickleclass Student:def __init__(self, name):self.name = namedef say_hi(self):print("name:", self.name)def save(self):with open(self.name, "wb") as f: # pickle 模塊操作文件必須是b 模式pickle.dump(self, f) # 利用pickle 模塊,將傳入的對象序列化到了文件中(json模塊不支持對象這種類型) @staticmethoddef get(name):with open(name, "rb") as f:obj = pickle.load(f) # 利用pickle 模塊,將文件中的對象反序列化成python中的對象return obj# 將rose 和 jack兩個從內存中對象序列化到文件中 stu = Student("rose") stu.save() stu2 = Student("jack") stu2.save()# 將他兩反序列化出來到內存中 obj = Student.get("rose") # 調用類中的方法(類綁定方法)從文件中將對象加載到內存中 print(obj.name) # 使用該對象獲取屬性值 # rose obj2 = Student.get("jack") print(obj2.name) # jackprint(Student.__name__) # 獲取類名 # Student# 反序列化出來的對象和序列化的那個對象已經不是同一個對象了 print(id(stu), id(obj)) # 2161209937816 2161209971880 print(stu.name, obj.name) # rose rose print(id(stu2), id(obj2)) # 2161209937872 2161209971824 print(stu2.name, obj2.name) # jack jack obj2.name = 'jack2' print(stu2.name, obj2.name) # jack jack2 將對象從內存中序列化反序列化到文件中英雄大亂斗(隨機)案例
import random import timeclass Hero:def __init__(self, name, health, attack, q_hurt, w_hurt, e_hurt):lcs = locals()lcs.pop('self')self.__dict__.update(lcs)def attack(self, enemy):print(f"-- {self.name} --使用普通攻擊攻擊了-- {enemy.name} --,造成了 {self.attack} 點傷害,{enemy.name} 剩余 {enemy.health} 點生命值。\033[0m")enemy.health -= self.attackdef Q(self, enemy):print(f"\033[0m-- {self.name} --使用Q技能攻擊了-- {enemy.name} --,造成了 {self.q_hurt} 點傷害,{enemy.name} 剩余 {enemy.health} 點生命值。\033[0m")enemy.health -= self.q_hurtdef W(self, enemy):print(f"\033[32m-- {self.name} --使用W技能攻擊了-- {enemy.name} --,造成了 {self.w_hurt} 點傷害,{enemy.name} 剩余 {enemy.health} 點生命值。\033[0m")enemy.health -= self.w_hurtdef E(self, enemy):print(f"\033[35m-- {self.name} --使用E技能攻擊了-- {enemy.name} --,造成了 {self.e_hurt} 點傷害,{enemy.name} 剩余 {enemy.health} 點生命值。\033[0m")enemy.health -= self.e_hurtdef check_hero(enemy, team):if enemy.health <= 0:print(f"\033[31m** {enemy.name} ** 陣亡。\033[0m")if team == 'blue':blue_team.remove(enemy)elif team == 'red':red_team.remove(enemy)def get_random_skill():return skill_list.get(random.randint(1, 4))def get_random_blue_hero():return blue_team[random.randint(0, len(blue_team) - 1)]def get_random_red_hero():return red_team[random.randint(0, len(red_team) - 1)]blue_team = [Hero('瑞文', 465, 65, 30, 25, 70),Hero('提莫', 300, 35, 50, 40, 60), ]red_team = [Hero('李白', 320, 60, 35, 29, 77),Hero('魯班', 280, 79, 35, 40, 80), ]skill_list = {1: Hero.attack,2: Hero.Q,3: Hero.W,4: Hero.E, }while len(red_team) > 0 and len(blue_team) > 0:skill = get_random_skill()blue = get_random_blue_hero()red = get_random_red_hero()flag = random.randint(0, 1)if flag:skill(blue, red)check_hero(red, 'red')else:skill(red, blue)check_hero(blue, 'blue')time.sleep(0.3)if len(red_team) == 0:print(f"藍色方獲勝!")print(f"藍色方所剩英雄狀態為:")for hero in blue_team:print(f"{hero.name} 剩余生命值 {hero.health}")elif len(blue_team) == 0:print(f"紅色方獲勝!")print(f"紅色方所剩英雄狀態為:")for hero in red_team:print(f"{hero.name} 剩余生命值 {hero.health}") 無注釋版注釋版
import random import time# 定義一個英雄類,表示英雄這一類的共同特征 class Hero:def __init__(self, name, health, attack, q_hurt, w_hurt, e_hurt):lcs = locals()lcs.pop('self')self.__dict__.update(lcs)'''********************************** 上述代碼講解 *************************************# 每次調用類生成對象的時候都會執行這里面的代碼,并將對象作為第一個參數self 傳進來print(locals())# {'e_hurt': 70, 'w_hurt': 25, 'q_hurt': 30, 'attack': 65, 'health': 465, 'name': '瑞文', 'self': <__main__.Hero object at 0x000002371823B278>}lcs = locals() # 這個locals()在 __init__ 函數里 可以獲取 __init__ 函數名稱空間里的那些名字,他是一個字典lcs.pop('self') # 發現上面的 locals() 多了一個 self 是不需要的,那就把它刪掉print(lcs)# {'e_hurt': 70, 'w_hurt': 25, 'q_hurt': 30, 'attack': 65, 'health': 465, 'name': '瑞文'}# 這些內容正是初始化對象時想做的事(只不過是 對象.e_hurt = 70 這樣的形式而已)self.__dict__.update(lcs) # 將這些東西放到對象里,就重復了n變 self.參數 = 參數 (self.name = name)這樣的動作print(self.__dict__)# {'e_hurt': 70, 'w_hurt': 25, 'q_hurt': 30, 'attack': 65, 'health': 465, 'name': '瑞文'}最初始的寫法:self.name = nameself.health = healthself.attack = attackself.q_hurt = q_hurtself.w_hurt = w_hurtself.e_hurt = e_hurt'''def attack(self, enemy):enemy.health -= self.attackprint(f"-- {self.name} --使用普通攻擊攻擊了-- {enemy.name} --,造成了 {self.attack} 點傷害,{enemy.name} 剩余 {enemy.health} 點生命值。\033[0m")def Q(self, enemy):enemy.health -= self.q_hurtprint(f"\033[0m-- {self.name} --使用Q技能攻擊了-- {enemy.name} --,造成了 {self.q_hurt} 點傷害,{enemy.name} 剩余 {enemy.health} 點生命值。\033[0m")def W(self, enemy):enemy.health -= self.w_hurtprint(f"\033[32m-- {self.name} --使用W技能攻擊了-- {enemy.name} --,造成了 {self.w_hurt} 點傷害,{enemy.name} 剩余 {enemy.health} 點生命值。\033[0m")def E(self, enemy):enemy.health -= self.e_hurtprint(f"\033[35m-- {self.name} --使用E技能攻擊了-- {enemy.name} --,造成了 {self.e_hurt} 點傷害,{enemy.name} 剩余 {enemy.health} 點生命值。\033[0m")def check_hero(enemy, team):if enemy.health <= 0:# \033[31m 這種格式的是打印時的顏色控制(顏色可參考 https://www.cnblogs.com/easypython/p/9084426.html)print(f"\033[31m** {enemy.name} ** 陣亡。\033[0m")if team == 'blue':blue_team.remove(enemy)elif team == 'red':red_team.remove(enemy)# 隨機選擇一種攻擊方式 def get_random_skill():# random_index = random.randint(1, 4)# random_skill = skill_list.get(random_index)# return random_skill # 函數名當做返回值返回,拿到可以直接加括號調用執行函數return skill_list.get(random.randint(1, 4)) # 上面代碼的簡便寫法# 隨機選擇一個藍色方英雄 def get_random_blue_hero():# 返回 blue_team 這個列表的索引為 random.randint(0, len(blue_team) - 1) 返回值的元素(英雄對象)# return blue_team[random.randint(0, len(blue_team) - 1)] # 下面幾行的簡便寫法random_idndex = random.randint(0, len(blue_team) - 1)hero = blue_team[random_idndex]return hero# 隨機選擇一個紅色方英雄 def get_random_red_hero():return red_team[random.randint(0, len(red_team) - 1)]# 藍色方英雄陣容 --- 可自定義 --- # 方便隨機數取英雄對象 blue_team = [# 英雄名 生命值 普通攻擊力 Q技能傷害 W技能傷害 E技能傷害# 瑞文 465 65 30 25 70Hero('瑞文', 465, 65, 30, 25, 70),Hero('提莫', 300, 35, 50, 40, 60),Hero('錘石', 600, 15, 20, 0, 32), ]# 紅色方英雄陣容 --- 可自定義 --- # 方便隨機數取英雄對象 red_team = [Hero('李白', 320, 60, 35, 29, 77),Hero('魯班', 280, 79, 35, 40, 80),Hero('盾山', 800, 3, 3, 3, 3), ]# 技能數字對應表(方便根據隨機數取技能) skill_list = {1: Hero.attack,2: Hero.Q,3: Hero.W,4: Hero.E, }def run():while len(red_team) > 0 and len(blue_team) > 0:# 調用方法隨機獲得一個技能skill = get_random_skill()# 調用方法隨機獲得一個藍色方英雄blue = get_random_blue_hero()# 調用方法隨機獲得一個紅色方英雄red = get_random_red_hero()# 隨機選擇一方為攻擊方(那么另一方就是被攻擊方)flag = random.randint(0, 1)if flag:skill(blue, red)check_hero(red, 'red')else:skill(red, blue)check_hero(blue, 'blue')# 暫停0.3秒,可以慢慢看戰斗過程time.sleep(0.3)# 如果有任意一方沒有英雄了,即游戲結束if len(red_team) == 0:print(f"藍色方獲勝!")print(f"藍色方所剩英雄狀態為:")for hero in blue_team:print(f"{hero.name} 剩余生命值 {hero.health}")elif len(blue_team) == 0:print(f"紅色方獲勝!")print(f"紅色方所剩英雄狀態為:")for hero in red_team:print(f"{hero.name} 剩余生命值 {hero.health}")if __name__ == '__main__':run()'''戰斗記錄************************** 省略n多中間戰斗步驟 *********************************-- 錘石 --使用W技能攻擊了-- 盾山 --,造成了 0 點傷害,盾山 剩余 42 點生命值。-- 盾山 --使用E技能攻擊了-- 瑞文 --,造成了 3 點傷害,瑞文 剩余 289 點生命值。-- 瑞文 --使用E技能攻擊了-- 盾山 --,造成了 70 點傷害,盾山 剩余 -28 點生命值。** 盾山 ** 陣亡。藍色方獲勝!藍色方所剩英雄狀態為:瑞文 剩余生命值 289錘石 剩余生命值 235戰斗記錄2************************** 省略n多中間戰斗步驟 *********************************-- 盾山 --使用普通攻擊攻擊了-- 錘石 --,造成了 3 點傷害,錘石 剩余 11 點生命值。-- 錘石 --使用普通攻擊攻擊了-- 盾山 --,造成了 15 點傷害,盾山 剩余 288 點生命值。-- 盾山 --使用E技能攻擊了-- 瑞文 --,造成了 3 點傷害,瑞文 剩余 -1 點生命值。** 瑞文 ** 陣亡。-- 盾山 --使用普通攻擊攻擊了-- 錘石 --,造成了 3 點傷害,錘石 剩余 8 點生命值。-- 盾山 --使用普通攻擊攻擊了-- 錘石 --,造成了 3 點傷害,錘石 剩余 5 點生命值。-- 盾山 --使用W技能攻擊了-- 錘石 --,造成了 3 點傷害,錘石 剩余 2 點生命值。-- 盾山 --使用Q技能攻擊了-- 錘石 --,造成了 3 點傷害,錘石 剩余 -1 點生命值。** 錘石 ** 陣亡。紅色方獲勝!紅色方所剩英雄狀態為:盾山 剩余生命值 288'''''' 有紅藍兩方英雄(可自定義個數)隨機一方英雄使用隨機攻擊方式攻擊另一方英雄,任意一方英雄全部陣亡則游戲結束每個英雄有 名字、生命值、普通攻擊、Q技能攻擊、W技能攻擊、E技能攻擊以及對應的傷害值當生命值為 0 時陣亡,不再參與戰斗 ''' 注釋版案例后續完善博客思路
調用類生成對象發生的一些事情(對比變量、模塊名稱空間生成等)屬性的查找順序(畫圖表示吧)先找自己的,再找父類的,一級一級往上找,直到基類object,再沒有報錯英雄大亂斗案例 序列化、反序列化對象(保存、讀取對象)(游戲退出,讀檔) 待完善內容(不算是面向對象的重點啦)?
轉載于:https://www.cnblogs.com/suwanbin/p/11240814.html
總結
以上是生活随笔為你收集整理的python面向对象基础-01的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 阶梯博弈(Staircase Nim)
- 下一篇: python第三次作业