【问题标题】:Making several classes with different values for their attributes: any way to avoid having to make several __init__?为它们的属性创建几个具有不同值的类:有什么方法可以避免必须创建几个 __init__?
【发布时间】:2020-04-13 20:39:01
【问题描述】:

我正在用 Python 3 制作一个基于文本的冒险游戏,我需要为不同的敌人类型制作类。每种敌人类型将有 5 个属性(当前生命值、最大生命值、攻击、速度和准确度)。我想知道是否有任何方法可以制作这些类而不必编写多个包含相同属性声明的初始化,如果这有意义的话。所以我可以有一个超类或包含这个__init__

的东西
    def __init__(self, hp, attack, speed, accuracy):

        #defines stats for the enemy
        self.maxhp = hp
        self.currenthp = hp
        self.attack = attack
        self.speed = speed
        self.accuracy = accuracy

只是将它“复制”到不同的敌人类型中。有什么办法可以做到这一点,还是我必须为每种敌人类型输入一个包含这个初始化的不同超类?

【问题讨论】:

  • 你真的需要不同的敌人类型吗?他们改变行为还是仅仅改变价值观?想想继承还是组合更适合您的目的
  • 您可以将参数打包到单独的类(最好是数据类)中,并且可以在从__init__ 调用的常用继承方法中进行解包(如果需要)。
  • @UnholySheep 现在我只需要更改属性值,但我想保持灵活性,以防我决定在每种敌人类型之间进行更多更改。
  • @MichaelButscher 我该怎么做呢?
  • 从 Python 3.7 开始,dataclasses 模块可以帮助创建类。

标签: python python-3.x class inheritance subclass


【解决方案1】:

对于您所描述的内容,您实际上并不需要 子类,您可以只拥有Enemy 类的不同实例。如果您确定有多个类,则可以将属性烘焙到 __init__ 方法中。这是两个选项...

实例化

class Enemy:
    def __init__(self, hp, attack, speed, accuracy):
        self.hp = hp
        self.attack = attack
        self.speed = speed
        self.accuracy = accuracy

Warrior = Enemy(100, 5, 7, 6)
Dragon = Enemy(500, 8, 2, 4)

子类

class Enemy:
    def __init__(self, hp, attack, speed, accuracy):
        self.hp = hp
        self.attack = attack
        self.speed = speed
        self.accuracy = accuracy

class Warrior(Enemy):
    def __init__(self):
        super().__init__(100, 5, 7, 6)

class Dragon(Enemy):
    def __init__(self):
        super().__init__(500, 8, 2, 4)

我希望这能回答你的问题。我会使用第一种方法,直到我真的需要更多特定于每个类的功能。从一开始我就不确定Dragon 还能比Enemy 更具体地做什么。如果您感到困惑,请在下方评论。


编辑:刚刚想到了您可以做的第三件事,即修改实例化方法。

实例化方法的问题在于,如果你想要多个一种类型,那么你必须不断地用它们的“敌人”属性重新声明它们。但是您可以通过使用__call__ 方法来避免这种情况。

class Enemy:
    def __init__(self, hp, attack, speed, accuracy):
        self.hp = hp
        self.attack = attack
        self.speed = speed
        self.accuracy = accuracy

    def __call__(self):
        return Enemy(self.hp, self.attack, self.speed, self.accuracy)

Warrior = Enemy(100, 5, 7, 6)
Dragon = Enemy(500, 8, 2, 4)

然后您可以在不使用Enemy(...) 的情况下创建WarriorDragon 的新实例:

warrior1 = Warrior()
warrior2 = Warrior()
dragon1 = Dragon()

assert warrior1 is not warrior2
assert dragon1 is not Dragon
assert isinstance(dragon1, Enemy)

【讨论】:

  • 我相信这就是我想要的!我不知道您可以将诸如整数之类的值直接传递给__init__。谢谢!
【解决方案2】:

据我所知,您需要一个超类“敌人”,并且对于“敌人”的每个子类,例如,“战士”、“龙”、“骑士”;每个敌人都有生命值,攻击力,准确性统计数据,但战士可能有不同的属性和方法,而不是像飞行的龙。在这种情况下,我会查看这篇关于继承的文章。继承允许您只创建一个超类并让每个子类“继承”这些属性:https://www.w3schools.com/python/python_inheritance.asp

例如:

class Subclass(Superclass):
  def __init__(self, SubclassAttribute1, SubclassAttribute2):
    super().__init__(SuperclassAttribute1, SuperclassAttribute2)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-01-12
    • 1970-01-01
    • 2021-07-24
    • 1970-01-01
    • 2017-01-20
    • 2015-05-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多