0

相當中級程序員,但Python初學者在這裏。我一直在做一場比賽,昨天我重新組織了所有的課程。在我最初只使用組合數據結構的地方,我現在使用了兩者的組合。我的問題來了,當我想產卵的球員。這是相關的代碼。Python:孩子繼承父母默認值,如果未指定

class Object(object): 
    def __init__(self, **kwargs): 
     DeaultValues={'x':0, 'y':0, 'name':None, 'texture':None, 'blocks':False, 'ObjectID':None, 'Fighter':None, 'Corpse':None, 'Skill':None, 'ai':None} 
     for key,value in DeaultValues.items(): 
      try: 
       vars(self)[key] = kwargs[key] 
      except ValueError: 
       vars(self)[key] = value 
      except KeyError: 
       vars(self)[key] = value 
     self.x = kwargs['x'] 
     self.y = kwargs['y'] 
     self.name=kwargs['name'] 
     self.blocks=kwargs['blocks'] 
     self.ObjectID=self.AttachID() 
     self.texture = kwargs['texture'] 

     #This section binds an actors compenents to itself 
     self.Corpse = kwargs['Corpse'] 
     if self.Corpse: 
      self.Corpse.owner = self 
     self.Skill=kwargs['Skill'] 
     if self.Skill: 
      self.Skill.owner = self 
     self.Fighter = kwargs['Fighter'] 
     if self.Fighter: 
      self.Fighter.owner = self 
     self.ai = kwargs['ai'] 
     if self.ai: 
      self.ai.owner = self 

class HighActor(Object): 
    def __init__(self, **kwargs): 
     super(HighActor, self).__init__(**kwargs) 

class Player(HighActor): 
    def __init__(self, Level=1, Xp=0, PreviousLevel=0, PreviousLevelThreshold=100, LevelThreshold=500, **kwargs): 
     super(Player, self).__init__(**kwargs) 
     self.LevelThreshold = LevelThreshold 
     self.PreviousLevelThreshold=PreviousLevelThreshold 
     self.PreviousLevel=PreviousLevel 
     self.Level = Level 
     self.Xp = Xp 

def SpawnPlayer(): 
    global player 
    FighterComponent = Fighter(MaxHp=100, Hp=100, IsHasted=[False, False], death_function=None) 
    CorpseComponent = Corpse() 
    SkillComponent = HighActorSkill() 
    player=Player(name="player", x=None, y=None, texture="player.png", blocks=True, ObjectID=None, Fighter=FighterComponent, Corpse=CorpseComponent, Skill=SkillComponent, ai=None) 

上面的代碼工作得很好,但它並沒有真正繼承任何東西。爲了讓播放器對象不出錯,我必須添加以將基礎對象類的所有屬性添加到播放器初始化中。如果我刪除了player = Player()語句中設置爲none的任何值,則會出現值錯誤或關鍵錯誤。我試圖通過讓一個默認值的字典來解決這個問題,該字典通過所有的kwargs循環,並且如果它們沒有值,則將它們設置爲默認值。這工作,直到我到任何組件。所以在沒有指定ai = none的情況下,我得到了重要的錯誤。我真的很喜歡以這樣的格式獲得我的代碼,如果我沒有爲任何基類對象類屬性指定值,則會傳入默認值,但如果我確實指定了值,則會傳遞給基類。我理想的最終結果將是有我的播放器實例化這個樣子:

def SpawnPlayer(): 
    global player 
    FighterComponent = Fighter(MaxHp=100, Hp=100, IsHasted=[False, False], death_function=None) 
    CorpseComponent = Corpse() 
    SkillComponent = HighActorSkill() 
    player=Player(name="player", texture="player.png", blocks=True, Fighter=FighterComponent, Corpse=CorpseComponent, Skill=SkillComponent) 

我有一個懷疑,我的產業是不工作100%,因爲我得到的錯誤,如果我離開了對象ID即使應分配因爲在低音類的init中它的設置等於getid(self)。因此,我要麼繼承問題(我真的與超級爭鬥)或我的對象的簽名問題,我不太清楚我的問題是什麼,更重要的是爲什麼。我並不反對大幅改變代碼簽名,因爲我仍然在編寫引擎,所以沒有任何東西依賴於此。應該做什麼?

回答

2

我認爲你的班級結構應該是不同的。每個類應該只有它需要的屬性,爲你打造了繼承,如添加新的:

class Object(object): 

    def __init__(self, x=0, y=0, name=None, **kwargs): 
     self.x = x 
     self.y = y 
     self.name = name 


class HighActor(Object): 

    def __init__(self, corpse=None, skill=None, **kwargs): 
     super(HighActor, self).__init__(**kwargs) 
     self.corpse = corpse 
     self.skill = skill 


class Player(HighActor): 

    def __init__(self, level=1, xp=0, **kwargs): 
     super(Player, self).__init__(**kwargs) 
     self.level = level 
     self.xp = xp 

在每個級別指定的屬性 - 所有Object S的關係有xyname,所有HighActor S的關係corpseskill,等等。現在你可以指定參數提供給任何的三個層次的層次結構,或者讓他們出去找默認值:

player = Player(name="player one", skill=100, xp=12) 

你可能有些東西不適合這個繼承方案 - 在你的模型中有多個單獨的繼承關係是可以的,不要強迫它!


這工作,因爲**kwargs在每個__init__「拖把了」任何關鍵字參數該方法沒有預料到字典kwargs,並且可以再把它們傳遞到一個新的水平結束。當你這樣做的時候,super(...).__init__(**kwargs),這個字典將字典解包回到關鍵字參數中,任何不存在的都將採用指定的默認值。

+0

遊戲中的大多數參與者都是基於對象類構建的。我在這裏省略了類似的方法,但是HighActor包含很多方法,並且還有一個額外的Child for HighActor,它具有區別性。玩家類的存在嚴格是因爲它實際上是對象類的進一步專業化。所有的角色都會死亡並使用異能,所以所有的對象都需要這些角色。我的代碼完全符合SoC。這甚至沒有解決實際問題。 –

+0

所有的Actor都可以是Object,但不是所有的Object都需要是Actor。爲什麼不在'Object'和'HighActor'之間添加'BaseActor'?另外,如果你只向我展示一些計劃,我只能幫你一點點! – jonrsharpe

+0

將基礎演員與通用對象區分開來的東西是他們成爲所有者的組件。假設我想要一個遊戲中的物體,這個物體是間歇泉,每轉一圈都會發出有毒的雲。我會將它初始化爲一個沒有戰鬥機或屍體組件的對象,但它會有一個技能組件來施放毒雲技能。這裏組合結構的使用是爲我提供了大量的靈活性,使得我創建的對象允許大量的對象和Actor的排列,而不需要管理一些荒謬的類。 –