日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
使用Python學(xué)習(xí)面對(duì)對(duì)象的編程

使用 Python 類使你的代碼變得更加模塊化。

創(chuàng)新互聯(lián)服務(wù)項(xiàng)目包括賓川網(wǎng)站建設(shè)、賓川網(wǎng)站制作、賓川網(wǎng)頁(yè)制作以及賓川網(wǎng)絡(luò)營(yíng)銷策劃等。多年來(lái),我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術(shù)優(yōu)勢(shì)、行業(yè)經(jīng)驗(yàn)、深度合作伙伴關(guān)系等,向廣大中小型企業(yè)、政府機(jī)構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,賓川網(wǎng)站推廣取得了明顯的社會(huì)效益與經(jīng)濟(jì)效益。目前,我們服務(wù)的客戶以成都為中心已經(jīng)輻射到賓川省份的部分城市,未來(lái)相信會(huì)繼續(xù)擴(kuò)大服務(wù)區(qū)域并繼續(xù)獲得客戶的支持與信任!

在我上一篇文章中,我解釋了如何通過(guò)使用函數(shù)、創(chuàng)建模塊或者兩者一起來(lái)使 Python 代碼更加模塊化。函數(shù)對(duì)于避免重復(fù)多次使用的代碼非常有用,而模塊可以確保你在不同的項(xiàng)目中復(fù)用代碼。但是模塊化還有另一種方法:類。

如果你已經(jīng)聽過(guò)面對(duì)對(duì)象編程object-oriented programming(OOP)這個(gè)術(shù)語(yǔ),那么你可能會(huì)對(duì)類的用途有一些概念。程序員傾向于將類視為一個(gè)虛擬對(duì)象,有時(shí)與物理世界中的某些東西直接相關(guān),有時(shí)則作為某種編程概念的表現(xiàn)形式。無(wú)論哪種表示,當(dāng)你想要在程序中為你或程序的其他部分創(chuàng)建“對(duì)象”時(shí),你都可以創(chuàng)建一個(gè)類來(lái)交互。

沒有類的模板

假設(shè)你正在編寫一個(gè)以幻想世界為背景的游戲,并且你需要這個(gè)應(yīng)用程序能夠涌現(xiàn)出各種壞蛋來(lái)給玩家的生活帶來(lái)一些刺激。了解了很多關(guān)于函數(shù)的知識(shí)后,你可能會(huì)認(rèn)為這聽起來(lái)像是函數(shù)的一個(gè)教科書案例:需要經(jīng)常重復(fù)的代碼,但是在調(diào)用時(shí)可以考慮變量而只編寫一次。

下面一個(gè)純粹基于函數(shù)的敵人生成器實(shí)現(xiàn)的例子:

  
 
 
  1. #!/usr/bin/env python3
  2.  
  3. import random
  4.  
  5. def enemy(ancestry,gear):
  6. enemy=ancestry
  7. weapon=gear
  8. hp=random.randrange(0,20)
  9. ac=random.randrange(0,20)
  10. return [enemy,weapon,hp,ac]
  11.  
  12. def fight(tgt):
  13. print("You take a swing at the " + tgt[0] + ".")
  14. hit=random.randrange(0,20)
  15. if hit > tgt[3]:
  16. print("You hit the " + tgt[0] + " for " + str(hit) + " damage!")
  17. tgt[2] = tgt[2] - hit
  18. else:
  19. print("You missed.")
  20.  
  21.  
  22. foe=enemy("troll","great axe")
  23. print("You meet a " + foe[0] + " wielding a " + foe[1])
  24. print("Type the a key and then RETURN to attack.")
  25.  
  26. while True:
  27. action=input()
  28.  
  29. if action.lower() == "a":
  30. fight(foe)
  31.  
  32. if foe[2] < 1:
  33. print("You killed your foe!")
  34. else:
  35. print("The " + foe[0] + " has " + str(foe[2]) + " HP remaining")

enemy 函數(shù)創(chuàng)造了一個(gè)具有多個(gè)屬性的敵人,例如譜系、武器、生命值和防御等級(jí)。它返回每個(gè)屬性的列表,表示敵人全部特征。

從某種意義上說(shuō),這段代碼創(chuàng)建了一個(gè)對(duì)象,即使它還沒有使用類。程序員將這個(gè) enemy 稱為對(duì)象,因?yàn)樵摵瘮?shù)的結(jié)果(本例中是一個(gè)包含字符串和整數(shù)的列表)表示游戲中一個(gè)單獨(dú)但復(fù)雜的東西。也就是說(shuō),列表中字符串和整數(shù)不是任意的:它們一起描述了一個(gè)虛擬對(duì)象。

在編寫描述符集合時(shí),你可以使用變量,以便隨時(shí)使用它們來(lái)生成敵人。這有點(diǎn)像模板。

在示例代碼中,當(dāng)需要對(duì)象的屬性時(shí),會(huì)檢索相應(yīng)的列表項(xiàng)。例如,要獲取敵人的譜系,代碼會(huì)查詢 foe[0],對(duì)于生命值,會(huì)查詢 foe[2],以此類推。

這種方法沒有什么不妥,代碼按預(yù)期運(yùn)行。你可以添加更多不同類型的敵人,創(chuàng)建一個(gè)敵人類型列表,并在敵人創(chuàng)建期間從列表中隨機(jī)選擇,等等,它工作得很好。實(shí)際上,Lua 非常有效地利用這個(gè)原理來(lái)近似了一個(gè)面對(duì)對(duì)象模型。

然而,有時(shí)候?qū)ο蟛粌H僅是屬性列表。

使用對(duì)象

在 Python 中,一切都是對(duì)象。你在 Python 中創(chuàng)建的任何東西都是某個(gè)預(yù)定義模板的實(shí)例。甚至基本的字符串和整數(shù)都是 Python type 類的衍生物。你可以在這個(gè)交互式 Python shell 中見證:

  
 
 
  1. >>> foo=3
  2. >>> type(foo)
  3. >>> foo="bar"
  4. >>> type(foo)

當(dāng)一個(gè)對(duì)象由一個(gè)類定義時(shí),它不僅僅是一個(gè)屬性的集合,Python 類具有各自的函數(shù)。從邏輯上講,這很方便,因?yàn)橹簧婕澳硞€(gè)對(duì)象類的操作包含在該對(duì)象的類中。

在示例代碼中,fight 的代碼是主應(yīng)用程序的功能。這對(duì)于一個(gè)簡(jiǎn)單的游戲來(lái)說(shuō)是可行的,但對(duì)于一個(gè)復(fù)雜的游戲來(lái)說(shuō),世界中不僅僅有玩家和敵人,還可能有城鎮(zhèn)居民、牲畜、建筑物、森林等等,它們都不需要使用戰(zhàn)斗功能。將戰(zhàn)斗代碼放在敵人的類中意味著你的代碼更有條理,在一個(gè)復(fù)雜的應(yīng)用程序中,這是一個(gè)重要的優(yōu)勢(shì)。

此外,每個(gè)類都有特權(quán)訪問自己的本地變量。例如,敵人的生命值,除了某些功能之外,是不會(huì)改變的數(shù)據(jù)。游戲中的隨機(jī)蝴蝶不應(yīng)該意外地將敵人的生命值降低到 0。理想情況下,即使沒有類,也不會(huì)發(fā)生這種情況。但是在具有大量活動(dòng)部件的復(fù)雜應(yīng)用程序中,確保不需要相互交互的部件永遠(yuǎn)不會(huì)發(fā)生這種情況,這是一個(gè)非常有用的技巧。

Python 類也受垃圾收集的影響。當(dāng)不再使用類的實(shí)例時(shí),它將被移出內(nèi)存。你可能永遠(yuǎn)不知道這種情況會(huì)什么時(shí)候發(fā)生,但是你往往知道什么時(shí)候它不會(huì)發(fā)生,因?yàn)槟愕膽?yīng)用程序占用了更多的內(nèi)存,而且運(yùn)行速度比較慢。將數(shù)據(jù)集隔離到類中可以幫助 Python 跟蹤哪些數(shù)據(jù)正在使用,哪些不在需要了。

優(yōu)雅的 Python

下面是一個(gè)同樣簡(jiǎn)單的戰(zhàn)斗游戲,使用了 Enemy 類:

  
 
 
  1. #!/usr/bin/env python3
  2.  
  3. import random
  4.  
  5. class Enemy():
  6. def __init__(self,ancestry,gear):
  7. self.enemy=ancestry
  8. self.weapon=gear
  9. self.hp=random.randrange(10,20)
  10. self.ac=random.randrange(12,20)
  11. self.alive=True
  12.  
  13. def fight(self,tgt):
  14. print("You take a swing at the " + self.enemy + ".")
  15. hit=random.randrange(0,20)
  16.  
  17. if self.alive and hit > self.ac:
  18. print("You hit the " + self.enemy + " for " + str(hit) + " damage!")
  19. self.hp = self.hp - hit
  20. print("The " + self.enemy + " has " + str(self.hp) + " HP remaining")
  21. else:
  22. print("You missed.")
  23.  
  24. if self.hp < 1:
  25. self.alive=False
  26.  
  27. # 游戲開始
  28. foe=Enemy("troll","great axe")
  29. print("You meet a " + foe.enemy + " wielding a " + foe.weapon)
  30.  
  31. # 主函數(shù)循環(huán)
  32. while True:
  33. print("Type the a key and then RETURN to attack.")
  34. action=input()
  35.  
  36. if action.lower() == "a":
  37. foe.fight(foe)
  38. if foe.alive == False:
  39. print("You have won...this time.")
  40. exit()

這個(gè)版本的游戲?qū)橙俗鳛橐粋€(gè)包含相同屬性(譜系、武器、生命值和防御)的對(duì)象來(lái)處理,并添加一個(gè)新的屬性來(lái)衡量敵人時(shí)候已被擊敗,以及一個(gè)戰(zhàn)斗功能。

類的第一個(gè)函數(shù)是一個(gè)特殊的函數(shù),在 Python 中稱為 init 或初始化的函數(shù)。這類似于其他語(yǔ)言中的構(gòu)造器,它創(chuàng)建了類的一個(gè)實(shí)例,你可以通過(guò)它的屬性和調(diào)用類時(shí)使用的任何變量來(lái)識(shí)別它(示例代碼中的 foe)。

Self 和類實(shí)例

類的函數(shù)接受一種你在類之外看不到的新形式的輸入:self。如果不包含 self,那么當(dāng)你調(diào)用類函數(shù)時(shí),Python 無(wú)法知道要使用的類的哪個(gè)實(shí)例。這就像在一間充滿獸人的房間里說(shuō):“我要和獸人戰(zhàn)斗”,向一個(gè)獸人發(fā)起。沒有人知道你指的是誰(shuí),所有獸人就都上來(lái)了。

CC-BY-SA by Buch on opengameart.org

類中創(chuàng)建的每個(gè)屬性都以 self 符號(hào)作為前綴,該符號(hào)將變量標(biāo)識(shí)為類的屬性。一旦派生出類的實(shí)例,就用表示該實(shí)例的變量替換掉 self 前綴。使用這個(gè)技巧,你可以在一間滿是獸人的房間里說(shuō):“我要和譜系是 orc 的獸人戰(zhàn)斗”,這樣來(lái)挑戰(zhàn)一個(gè)獸人。當(dāng) orc 聽到 “gorblar.orc” 時(shí),它就知道你指的是誰(shuí)(他自己),所以你得到是一場(chǎng)公平的戰(zhàn)斗而不是斗毆。在 Python 中:

  
 
 
  1. gorblar=Enemy("orc","sword")
  2. print("The " + gorblar.enemy + " has " + str(gorblar.hp) + " remaining.")

通過(guò)檢索類屬性(gorblar.enemy 或 gorblar.hp 或你需要的任何對(duì)象的任何值)而不是查詢 foe[0](在函數(shù)示例中)或 gorblar[0] 來(lái)尋找敵人。

本地變量

如果類中的變量沒有以 self 關(guān)鍵字作為前綴,那么它就是一個(gè)局部變量,就像在函數(shù)中一樣。例如,無(wú)論你做什么,你都無(wú)法訪問 Enemy.fight 類之外的 hit 變量:

  
 
 
  1. >>> print(foe.hit)
  2. Traceback (most recent call last):
  3. File "./enclass.py", line 38, in
  4. print(foe.hit)
  5. AttributeError: 'Enemy' object has no attribute 'hit'
  6.  
  7. >>> print(foe.fight.hit)
  8. Traceback (most recent call last):
  9. File "./enclass.py", line 38, in
  10. print(foe.fight.hit)
  11. AttributeError: 'function' object has no attribute 'hit'

hit 變量包含在 Enemy 類中,并且只能“存活”到在戰(zhàn)斗中發(fā)揮作用。

更模塊化

本例使用與主應(yīng)用程序相同的文本文檔中的類。在一個(gè)復(fù)雜的游戲中,我們更容易將每個(gè)類看作是自己獨(dú)立的應(yīng)用程序。當(dāng)多個(gè)開發(fā)人員處理同一個(gè)應(yīng)用程序時(shí),你會(huì)看到這一點(diǎn):一個(gè)開發(fā)人員負(fù)責(zé)一個(gè)類,另一個(gè)開發(fā)人員負(fù)責(zé)主程序,只要他們彼此溝通這個(gè)類必須具有什么屬性,就可以并行地開發(fā)這兩個(gè)代碼塊。

要使這個(gè)示例游戲模塊化,可以把它拆分為兩個(gè)文件:一個(gè)用于主應(yīng)用程序,另一個(gè)用于類。如果它是一個(gè)更復(fù)雜的應(yīng)用程序,你可能每個(gè)類都有一個(gè)文件,或每個(gè)邏輯類組有一個(gè)文件(例如,用于建筑物的文件,用于自然環(huán)境的文件,用于敵人或 NPC 的文件等)。

將只包含 Enemy 類的一個(gè)文件保存為 enemy.py,將另一個(gè)包含其他內(nèi)容的文件保存為 main.py。

以下是 enemy.py

  
 
 
  1. import random
  2.  
  3. class Enemy():
  4. def __init__(self,ancestry,gear):
  5. self.enemy=ancestry
  6. self.weapon=gear
  7. self.hp=random.randrange(10,20)
  8. self.stg=random.randrange(0,20)
  9. self.ac=random.randrange(0,20)
  10. self.alive=True
  11.  
  12. def fight(self,tgt):
  13. print("You take a swing at the " + self.enemy + ".")
  14. hit=random.randrange(0,20)
  15.  
  16. if self.alive and hit > self.ac:
  17. print("You hit the " + self.enemy + " for " + str(hit) + " damage!")
  18. self.hp = self.hp - hit
  19. print("The " + self.enemy + " has " + str(self.hp) + " HP remaining")
  20. else:
  21. print("You missed.")
  22.  
  23. if self.hp < 1:
  24. self.alive=False

以下是 main.py

  
 
 
  1. #!/usr/bin/env python3
  2.  
  3. import enemy as en
  4.  
  5. # game start
  6. foe=en.Enemy("troll","great axe")
  7. print("You meet a " + foe.enemy + " wielding a " + foe.weapon)
  8.  
  9. # main loop
  10. while True:
  11. print("Type the a key and then RETURN to attack.")
  12.  
  13. action=input()
  14.  
  15. if action.lower() == "a":
  16. foe.fight(foe)
  17.  
  18. if foe.alive == False:
  19. print("You have won...this time.")
  20. exit()

導(dǎo)入模塊 enemy.py 使用了一條特別的語(yǔ)句,引用類文件名稱而不用帶有 .py 擴(kuò)展名,后跟你選擇的命名空間指示符(例如,import enemy as en)。這個(gè)指示符是在你調(diào)用類時(shí)在代碼中使用的。你需要在導(dǎo)入時(shí)添加指示符,例如 en.Enemy,而不是只使用 Enemy()。

所有這些文件名都是任意的,盡管在原則上不要使用罕見的名稱。將應(yīng)用程序的中心命名為 main.py 是一個(gè)常見約定,和一個(gè)充滿類的文件通常以小寫形式命名,其中的類都以大寫字母開頭。是否遵循這些約定不會(huì)影響應(yīng)用程序的運(yùn)行方式,但它確實(shí)使經(jīng)驗(yàn)豐富的 Python 程序員更容易快速理解應(yīng)用程序的工作方式。

在如何構(gòu)建代碼方面有一些靈活性。例如,使用該示例代碼,兩個(gè)文件必須位于同一目錄中。如果你只想將類打包為模塊,那么必須創(chuàng)建一個(gè)名為 mybad 的目錄,并將你的類移入其中。在 main.py 中,你的 import 語(yǔ)句稍有變化:

  
 
 
  1. from mybad import enemy as en

兩種方法都會(huì)產(chǎn)生相同的結(jié)果,但如果你創(chuàng)建的類足夠通用,你認(rèn)為其他開發(fā)人員可以在他們的項(xiàng)目中使用它們,那么后者更好。

無(wú)論你選擇哪種方式,都可以啟動(dòng)游戲的模塊化版本:

  
 
 
  1. $ python3 ./main.py
  2. You meet a troll wielding a great axe
  3. Type the a key and then RETURN to attack.
  4. a
  5. You take a swing at the troll.
  6. You missed.
  7. Type the a key and then RETURN to attack.
  8. a
  9. You take a swing at the troll.
  10. You hit the troll for 8 damage!
  11. The troll has 4 HP remaining
  12. Type the a key and then RETURN to attack.
  13. a
  14. You take a swing at the troll.
  15. You hit the troll for 11 damage!
  16. The troll has -7 HP remaining
  17. You have won...this time.

游戲啟動(dòng)了,它現(xiàn)在更加模塊化了。現(xiàn)在你知道了面對(duì)對(duì)象的應(yīng)用程序意味著什么,但最重要的是,當(dāng)你向獸人發(fā)起決斗的時(shí)候,你知道是哪一個(gè)。 


標(biāo)題名稱:使用Python學(xué)習(xí)面對(duì)對(duì)象的編程
網(wǎng)站URL:http://m.5511xx.com/article/dhcggpe.html