简体   繁体   中英

Child object 'str' object is not callable, unable to rectify from other similar posts

I am attempting to create a child object from random variables within a list. I have included all code that I have tried. Googling the errors brings up many posts and solutions, none of which seem to be exactly parallel enough for me to utilize. Thanks for your time and consideration.

import random


class Monster:

    def __init__(self, name, level):
        self.name = name
        self.level = level


class Dragon(Monster):

    def breathe_fire(self):
        print("The Dragon breathes fire!")


class Skeleton(Monster):

    def strikes(self):
        print("The Skeleton strikes with its sword!")


MONSTERS = ["Skeleton", "Dragon"]
monster_type = random.choice(MONSTERS)
monster_level = 1
monster_stats = [monster_type, monster_level]
print(monster_stats)
# create object from child class and pass stats
#monster = random.choice(MONSTERS(*monster_stats)) <--'list' object is not callable
#monster = Dragon(*monster_stats) # <-- works, but is useless for my purposes
#monster = monster_type(*monster_stats)  <---  'str' object is not callable

You have quotes ("") around Skeleton and Dragon - making them strings

Remove the quotes to reference the class rather than the string

Note: this will not fix the error in this line: monster = random.choice(MONSTERS(*monster_stats))

To fix this, use: monster = random.choice(MONSTERS)(*monster_stats)

Try this:

import random


class Monster:
    name = None

    def __init__(self, level):
        self.level = level


class Dragon(Monster):
    name = "Dragon"

    def attack(self):
        print("The Dragon breathes fire!")


class Skeleton(Monster):
    name = "Skeleton"

    def attack(self):
        print("The Skeleton strikes with its sword!")


MONSTERS = [Skeleton, Dragon]

monster_cls = random.choice(MONSTERS)
monster_level = 1
monster_stats = [monster_level]  # maybe you have other stats too

monster = monster_cls(*monster_stats)

The main fix is to have a list of classes instead of strings: MONSTERS = [Skeleton, Dragon]

A couple of other suggestions:

  • if the name is the type of the monster (and not an individual name like Smaug) then it doesn't need to be an arg to __init__
  • you might find the rest of the code easier if all the monsters have a common method for making an attack, otherwise when you make a battle you will have to have lots of code like "if monster is a Dragon then breathe_fire else if monster is a Skeleton then strike "

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM