Home > Enterprise >  Is it possible to "dynamically" modify an instance attribute? Possibly by matching a strin
Is it possible to "dynamically" modify an instance attribute? Possibly by matching a strin

Time:09-16

Essentially I'd like to write a setter that can modify different class variables depending on input. For example:

@dataclass
class Rocket:
    fuel: int
    oxidizer: int
    weight: int
    power: int
    # I actually have tons of variables

    def decrease_value(self, value, amount):
        # magically match value to self.`value`
        # subtract amount from the matching class variable

r = Rocket
r.decrease_value('fuel', 200)
r.decrease_value('weight', 55)

Something like this would be much nicer than the huge else if chain that I'd rather not write.

CodePudding user response:

Yes, you can, but note that this is not the best practice as static code analyzers won't be able to find your bugs:

from dataclasses import dataclass

@dataclass
class Rocket:
    fuel: int
    oxidizer: int
    weight: int
    power: int
    # I actually have tons of variables

    def decrease_value(self, value, amount):
        if value in self.__dict__:    # Check if the attribute name is valid
            self.__dict__[value] -= amount


r = Rocket(fuel=1000, oxidizer=2000, weight=3000, power=4000)
r.decrease_value('fuel', 200)
r.decrease_value('weight', 55)
r.decrease_value('foobar', 55)   # This will not cause an error

print(r)

This will print

Rocket(fuel=800, oxidizer=2000, weight=2945, power=4000)

CodePudding user response:

You can achieve this using through getattr and setattr methods like

class Rocket: 
    fuel: int = 0 
    oxidizer: int = 0 
    weight: int = 0 
    power: int = 0 
    # I actually have tons of variables 
 
    def __init__(self, fuel, oxidizer, weight, power):
        # initialize the initial value
        self.fuel = fuel 
        self.oxidizer = oxidizer 
        self.weight = weight 
        self.power = power 

    def decrease_value(self, value, amount): 
        # magically match value to self.`value` 
        # subtract amount from the matching class variable 
        try: 
            value_is = getattr(self, value) 
            setattr(self, value, (value_is - amount)) 
        except AttributeError: 
            print(f'{value} variable is not available in Rocket class') 
 
r = Rocket(fuel=100, oxidizer=100, weight=100, power=100) 
r.decrease_value('fuel', 200) 
r.decrease_value('weight', 55)

see the getattr and setattr method in detail it will give you more understanding

  • Related