我在決定在python程序中放置方法時遇到了麻煩,它似乎像我習慣依賴的鴨子打字方法與我的OOP本能不一致。如何使用鴨打字來編寫OOP一致的代碼?
爲了說明,假設我們有三個類:Hero,Sword和Apple。英雄可以裝備一把劍,英雄可以吃一個蘋果。
如果我要按照我的OOP的直覺,我覺得代碼是這樣的:
duckless.py
class Hero:
def __init__(self):
self.weapon = None
self.inTummy = None
def equip(self, weapon):
weapon.define()
print("I shall equip it.")
self.weapon = weapon
def eat(self, food):
food.define()
print("I shall consume it.")
self.inTummy = food
class Sword:
def define(self):
print("'tis a shiny sword")
class Apple:
def define(self):
print("'tis a plump apple")
hero = Hero()
swd = Sword()
apl = Apple()
hero.equip(swd)
hero.eat(apl)
這感覺非常的直觀性和可讀性。
如果我是鴨類,不過,我覺得自己的代碼會是這個樣子:
duckfull.py
class Hero:
def __init__(self):
self.weapon = None
self.inTummy = None
def onEquip(self):
print("I shall equip it.")
def onEat(self):
print("I shall eat it.")
class Sword:
def define(self):
print("'tis a shiny sword")
def equip(self, hero):
self.define()
hero.onEquip()
hero.weapon = self
class Apple:
def define(self):
print("'tis a plump apple")
def eat(self, hero):
self.define()
hero.onEat()
hero.inTummy = self
hero = Hero()
swd = Sword()
apl = Apple()
swd.equip(hero)
apl.eat(hero)
鴨子類型的代碼具有明顯的優勢我可以執行嘗試 - 除了在任何時間,以確定我是否執行「合法」的行動:
try:
apl.equip()
except AttributeError:
print("I can't equip that!")
這感覺非常pythonic,而替代方案會要求我執行可怕的類型檢查。
然而,從面向對象的角度來看,感覺怪怪的是一個劍負責裝備本身,它接收一個英雄作爲參數。裝備行爲看起來像是由英雄執行的動作,因此,我覺得該方法應該屬於英雄類。
def eat(self, hero):
self.define()
hero.onEat()
hero.inTummy = self
感覺非常陌生。
要麼是更pythonic嗎?更多的OOP是否一致?我應該一起看看不同的解決方案嗎?
在此先感謝。
我認爲這屬於我們的代碼審查頁面,而不是StackOverflow。 – Prune
對不起。我是新來的網站。有沒有辦法在那裏提出這個問題,或者我應該刪除它並在合適的頁面中重新提問? – zayora
你可以定義一個'Item'超類,並讓'Hero'實現一個'activate()'方法,它調用被覆蓋的'Item'的'activate()'函數?這樣,你可以簡單地調用hero.activate(item),並根據你的Item的子類,它會相應地調用'eat()'或'equip()'。 – MeetTitan