Python 利用类中的相同属性

Python 利用类中的相同属性,python,class,Python,Class,在本课程中: class Hero(): def __init__(self, Type, name): self.Type = Type self.name = name self.atk = 'Undefined' if Type == 'Paladin': self.hp = 150 self.dmg = [10, 20] self.atk =

在本课程中:

class Hero():
    def __init__(self, Type, name):
        self.Type = Type
        self.name = name
        self.atk = 'Undefined'

        if Type == 'Paladin':
            self.hp = 150
            self.dmg = [10, 20]
            self.atk = random.randint(self.dmg[0], self.dmg[1])
            self.defence = 25
            self.dodge = 5

        elif Type == 'Mage':
            self.hp = 70
            self.dmg = [60, 70]
            self.atk = random.randint(self.dmg[0], self.dmg[1])
            self.defence = 15
            self.dodge = 8

        elif Type == 'Archer':
            self.hp = 100
            self.dmg = [40, 50]
            self.atk = random.randint(self.dmg[0], self.dmg[1])
            self.defence = 10
            self.dodge = 13
我注意到每个if语句都有hp、dmg、atk、Defense和dodge。既然python是面向对象的,那么有没有一种方法可以利用它而不需要手动编写所有这些东西呢

您可以使用继承并创建Hero类的3个子类来移动代码

Hero类,您可以在其中编写一个util方法来创建不同类型的Hero

class Hero():
    def __init__(self, Type, name):
        self.name = name
        self.atk = 'Undefined'

    def _init_atk(self):
        self.atk = random.randint(self.dmg[0], self.dmg[1])

    @staticmethod
    def get_hero(hero_type, name):
        if hero_type == 'Paladin':
          return Paladin(name)
        elif hero_type == 'Mage':
          return Mage(name)
        elif hero_type == 'Archer':
          return Archer(name)
        return None
英雄类,它们定义了自己的属性值

class Paladin(Hero):
    def __init__(self,name):
        super(Paladin, self).__init(name)
        self.hp = 150
        self.dmg = [10, 20]
        self.defence = 25
        self.dodge = 5
        self._init_atk()

class Mage(Hero):
    def __init__(self,name):
        super(Mage, self).__init(name)
        self.hp = 70
        self.dmg = [60, 70]
        self.defence = 15
        self.dodge = 8
        self._init_atk()

class Archer(Hero):
    def __init__(self,name):
        super(Archer, self).__init(name)
        self.hp = 100
        self.dmg = [40, 50]
        self.defence = 10
        self.dodge = 13
        self._init_atk()
然后您可以创建类似于

a = Archer("RobinHood")
b = Hero.get_hero("Mage", "HarryPotter")
您可以使用继承并创建Hero类的3个子类来移动代码

Hero类,您可以在其中编写一个util方法来创建不同类型的Hero

class Hero():
    def __init__(self, Type, name):
        self.name = name
        self.atk = 'Undefined'

    def _init_atk(self):
        self.atk = random.randint(self.dmg[0], self.dmg[1])

    @staticmethod
    def get_hero(hero_type, name):
        if hero_type == 'Paladin':
          return Paladin(name)
        elif hero_type == 'Mage':
          return Mage(name)
        elif hero_type == 'Archer':
          return Archer(name)
        return None
英雄类,它们定义了自己的属性值

class Paladin(Hero):
    def __init__(self,name):
        super(Paladin, self).__init(name)
        self.hp = 150
        self.dmg = [10, 20]
        self.defence = 25
        self.dodge = 5
        self._init_atk()

class Mage(Hero):
    def __init__(self,name):
        super(Mage, self).__init(name)
        self.hp = 70
        self.dmg = [60, 70]
        self.defence = 15
        self.dodge = 8
        self._init_atk()

class Archer(Hero):
    def __init__(self,name):
        super(Archer, self).__init(name)
        self.hp = 100
        self.dmg = [40, 50]
        self.defence = 10
        self.dodge = 13
        self._init_atk()
然后您可以创建类似于

a = Archer("RobinHood")
b = Hero.get_hero("Mage", "HarryPotter")

您可以使用继承从超类派生各种英雄角色,并为每个新类型指定一组特定的值;您还可以为他们提供特定的属性和行为:

使用类变量存储值简化了代码:

from abc import ABC
import random


class Hero(ABC):   # this cannot be instantiated 
    def __init__(self, name):
        self.name = name
        self.atk = random.randint(self.dmg[0], self.dmg[1])
        self.hp = self.__class__.hp
        self.dmg = list(self.__class__.dmg)
        self.defence = self.__class__.defence
        self.dodge = self.__class__.dodge
    def __str__(self):
        return f'{self.__class__.__qualname__}: {self.name}, atk: {self.atk}, hp: {self.hp}, dmg: {self.dmg}, defense: {self.defence}, dodge: {self.dodge}'


class Paladin(Hero):
    hp = 150
    dmg = (10, 20)
    defence = 25
    dodge = 5
    def __init__(self, name):
        super().__init__(name)


class Mage(Hero):
    hp = 70
    dmg = (60, 70)
    defence = 15
    dodge = 8
    def __init__(self, name, spells):
        super().__init__(name)
        self.spells = spells[:]
    def __str__(self):
        return f'{super().__str__()}\n\tspells: {self.spells}'


class Archer(Hero):
    hp = 100
    dmg = (40, 50)
    defence = 10
    dodge = 13
    def __init__(self, name):
        super().__init__(name)


A = Archer('Guillaume Tell')
B = Mage('Gandalf', ['quadratus lumborum', 'rectus femoris'])
C = Paladin('Ali Baba')

print(A)
print(B)
print(C)
输出:
您可以使用继承从超类派生各种英雄角色,并为每个新类型指定一组特定的值;您还可以为他们提供特定的属性和行为:

使用类变量存储值简化了代码:

from abc import ABC
import random


class Hero(ABC):   # this cannot be instantiated 
    def __init__(self, name):
        self.name = name
        self.atk = random.randint(self.dmg[0], self.dmg[1])
        self.hp = self.__class__.hp
        self.dmg = list(self.__class__.dmg)
        self.defence = self.__class__.defence
        self.dodge = self.__class__.dodge
    def __str__(self):
        return f'{self.__class__.__qualname__}: {self.name}, atk: {self.atk}, hp: {self.hp}, dmg: {self.dmg}, defense: {self.defence}, dodge: {self.dodge}'


class Paladin(Hero):
    hp = 150
    dmg = (10, 20)
    defence = 25
    dodge = 5
    def __init__(self, name):
        super().__init__(name)


class Mage(Hero):
    hp = 70
    dmg = (60, 70)
    defence = 15
    dodge = 8
    def __init__(self, name, spells):
        super().__init__(name)
        self.spells = spells[:]
    def __str__(self):
        return f'{super().__str__()}\n\tspells: {self.spells}'


class Archer(Hero):
    hp = 100
    dmg = (40, 50)
    defence = 10
    dodge = 13
    def __init__(self, name):
        super().__init__(name)


A = Archer('Guillaume Tell')
B = Mage('Gandalf', ['quadratus lumborum', 'rectus femoris'])
C = Paladin('Ali Baba')

print(A)
print(B)
print(C)
输出:
您可以将类型设置为子类,这将是OOP的范例用法。并不是说它减少了代码行的数量。您还可以创建一个类HeroStats,将其实例传递给构造函数并分配它。然而,这并不是一个好的OOP风格,扩展起来很麻烦,例如,尽管它可能会减少您最终的输入量,假设您有很多类型和大量的stats.delegation模式又称类继承,您可以将self.atk=random.randintself.dmg[0],self.dmg[1]转换为一个私有方法,如_set_atk,以节省少量代码。您可以将类型设置为子类,这将是OOP的典型用法。并不是说它减少了代码行的数量。您还可以创建一个类HeroStats,将其实例传递给构造函数并分配它。然而,这并不是一个好的OOP风格,扩展起来很麻烦,例如,尽管它可能会减少您最终的输入量,假设您有很多类型和大量的stats.delegation模式又称类继承,您可以将self.atk=random.randintself.dmg[0],self.dmg[1]进入像_set_atk这样的私有方法来保存一点点代码。为什么你有Hero.get_Hero?我的意思是,从父类初始化子类似乎很奇怪。它也会被继承,所以b=Archer.get_heroMage,HarryPotter会工作,这似乎也很奇怪。@wjandrea只是为了保持它使用“条件”来创建对象的方式,这是可移动的;你为什么会有英雄呢?我的意思是,从父类初始化子类似乎很奇怪。它也会被继承,所以b=Archer.get_heroMage,HarryPotter会工作,这似乎也很奇怪。@wjandrea只是为了保持它使用“条件”来创建对象的方式,这是可移动的;