0

What I'd like to do is have a list of strings be used as attributes of an object when it is created. I've seen another topic discuss using a list of strings as variables by creating a dictionary, but this seems to keep the strings as strings, which won't work for me, I don't think. Here's what I would like to work. It's a DnD exercise:

abilities = ['strength', 'dexterity', 'constitution', 'intelligence', 'wisdom', 'charisma']


class Character:
    def __init__(self):
        for ability in abilities:
            self.ability = roll_ability()       #this is a call to an outside function

Thanks!

1
  • 2
    There's almost certainly a duplicate for this, but I'm having trouble finding a good one. Maybe stackoverflow.com/q/30790947/1126841, but I'm not certain enough to close this as a duplicate myself. Commented Jan 21, 2020 at 19:09

3 Answers 3

2

Use setattr:

def __init__(self):
    for ability in abilities:
        setattr(self, ability, roll_ability())
Sign up to request clarification or add additional context in comments.

3 Comments

This is a bad practice to use global vars and specially in class initialization.
Pretend abilities = self.abilities is the first line, and that Character.abilities is a class attribute.
Or just pretend abilities is named ABILITIES indicating that it is supposed to be used as a constant. Global variables are only bad practice when they aren't constant; Character is also a global variable holding a reference to the class, for example.
0

Since this is for a D&D game, it's likely you will need to access the ability scores dynamically too; for example, a saving_throw method could take the name of the ability you are using to roll a saving throw. In that case, it is usually a better design to use a dictionary instead of separate attributes:

class Character:
    def __init__(self):
        self.abilities = { ability: roll_ability() for ability in abilities }

    def get_ability_score(self, ability):
        return self.abilities[ability]

    def saving_throw(self, ability, bonus=0):
        return roll_dice(20) + self.abilities[ability] + bonus

1 Comment

I don't know. I'm doing it as an exercise on Exercism, so it has to pass their test, which I think looks for specific things. I'm not sure a dictionary would work.
0

This can be yet another option to go with avoiding using global vars:

class Something:

    def __init__(self, *args):
        for ability in args:
            setattr(self, ability, roll_ability())


abilities = ['strength', 'dexterity', 'constitution', 'intelligence', 'wisdom', 'charisma']
s = Something(*abilities)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.