Home > Blockchain >  How to update a class variable that depends on another class variable
How to update a class variable that depends on another class variable

Time:12-09

I'm a student currently learning Python and was wondering how the question in the title could be solved. For a project, I'm creating a game that uses a class to store certain variables for different characters. Below is a portion of the class:

class character(object):
    def __init__(self, vitality):
            self.vitality = vitality
            self.stats = f'Vitality: {self.vitality}'

I haven't included the full class as I have like 41 variables in it, some of which are based on a combination of the others, but this is the gist of it.

Later in the code, I let the user choose a variable to increment by 1 in order to level up:

levelUpChoice = ''
levelUpChoiceList = ['1', '2', '3', '4', '5', '6', '7']

while levelUpChoice == '':
    levelUpChoice = input('What stat would you like to increase?\n1) Vitality\n2) Endurance\n3) Strength\n4) Dexterity\n5) Wisdom\n6) Faith\n7) Luck\n\n  > ')

    if levelUpChoice not in levelUpChoiceList:
        levelUpChoice = ''
        print('That is not an accepted response!\nUse a number 1-7.')

if int(levelUpChoice) == 1:
    charClass.vitality  = 1

However, the class variable called "stats" doesn't get updated when I increment "vitality" by 1, even though it's based on it. As I literally learned about classes and how to generally use them 2 days ago, I'm not quite sure how to deal with this, but I need a solution for the project to have full functionality. Seeing as my most important class variables depend on the basic ones I plan on changing, I really need a solution.

Any tips or suggestions would be greatly appreciated.

CodePudding user response:

Make stats a property. That will cause it to be re-computed every time you access it. A property is essentially syntactic sugar around a method that makes it act like any other type of attribute -- i.e. you can treat self.stats as a regular string even though it's actually a function call.

class Character:
    def __init__(self, vitality: int):
        self.vitality = vitality

    @property
    def stats(self) -> str:
        return f'Vitality: {self.vitality}'

(Note that explicitly inheriting from object isn't necessary, and standard Python style is to capitalize class names.)

CodePudding user response:

Some ways to fix that:

update the vitality by a setter and also change the stats:

class character(object):
    def __init__(self, vitality):
            self.vitality = vitality
            self.stats = f'Vitality: {self.vitality}'

    def set_vitality(self, val):
        self.vitality = val
        self.stats = f'Vitality: {val}'

Or a more advanced concept use @property

class character(object):
    def __init__(self, vitality):
            self.vitality = vitality

    @property
    def stats(self):
        return f'Vitality: {self.vitality}'

CodePudding user response:

If all you need is to update the stats attribute, the easiest option is probably to make it a property.

class character(object):
    def __init__(self, vitality):
            self.vitality = vitality

    #Accessed when character.stats is called
    #and constructs string at call time
    @property
    def stats(self):
        return f'Vitality: {self.vitality}'

There's quite a detailed discussion of properties here: How does the @property decorator work in Python?

  • Related