Forum Archive

OOP Inheritance Problem

craigmrock

Thinking I set up this inheritance structure right, but getting an error that “ init() takes 1 positional argument but 15 were given.” Any thoughts?

import random

#Player Info
class Player:
    def __init__ (self, name, race, subrace, age, subclass,hair, eyes, height, weight, strength, speed, intelligence, knowledge, attack, defense,**kwargs):

        for key,value in kwargs.items():
            setattr(self,key,value)

        self.name = name
        self.race = race
        self.subrace = subrace
        self.age = age
        self.subclass = subclass
        self.hair = hair
        self.eyes = eyes
        self.height = height
        self.weight = weight
        self.strength = random.randint(6,18)
        self.speed = random.randint(6,18)
        self.intelligence = random.randint(6,18)
        self.knowledge = random.randint(6,18)
        self.attack = random.randint(2,6)
        self.defense = random.randint(2,6)


    def __str__ (self):
        return ("Name: {}, Race: {}, Subrace: {}, Age: {}, Subclass: {}, Hair: {}, Eyes: {}, Height: {}, Weight:{}, Strength: {}, Speed: {}, Intelligence: {}, Knowledge: {}, Attack: {}, Defense: {}").format(self.name,self.race,self.subrace,
        self.age,self.subclass,self.hair,self.eyes,
        self.height,self.weight,self.strength, self.speed,self.intelligence,self.knowledge,
        self.attack,self.defense)

p1 = Player("Rob", "Human", "Hunter", "25", "none", "Brown", "Green", "72in","185"," "," "," "," "," "," ")
print(p1)

#Special Classes for Players
class Vampire(Player):
        def __init__ (self):
            data = {
                "strength": random.randint(14,18),
                "speed": random.randint(14,18),
                "intelligence": random.randint(14,18),
                "knowledge": random.randint(14,18)
            }
            super().__init__(**data)

p2 = Vampire("Jon", "Vampire", "Archaea", "500", "none", "Black", "Red", "84in","225"," "," "," "," "," ")
print(p2)
JonB

I think your Vampire init needs to look like

def __init__(self, *args, **kwargs):
    super().__init__(self,*args, **kwargs)
   #now, override defaults with class specific
    data = {
                "strength": random.randint(14,18),
                "speed": random.randint(14,18),
                "intelligence": random.randint(14,18),
                "knowledge": random.randint(14,18)
            }
    for key,value in data.items():
            setattr(self,key,value)

Your Player class probably isnt doing what you expect -- for instance, you take a named strength argument -- which you ignore. Then, you apply kwargs, such as strength. Then you overwrite it with the default.

Your approach seems very fragile -- do you want to enforce limits by class? In that case, each class should store the min/max limits, then attributes can be checked against those limits. Then you might simply have a roll() method that goes through each attribute, and randints between the limits -- i.e one loop, not fifty bazillion places where you call randint. less chance of errors.