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的排列,而不需要管理一些荒谬的类。 –