0

I am trying to use a method within an object to selectively change specific properties of that object. I haven't been able to figure out how to get the method to recognize the values that I pass to it as indicating the preexisting properties.

class Attributes(object):
        def __init__(self, strength, speed):
            self.strength = strength
            self.speed = speed
        
        def increase(self, attribute, amount):
        
            self.attribute += amount
       
    You = Attributes(1, 2)
    

    You.increase(strength, 5)

    print(You.strength)    

The console tells me "strength is not defined".

returning the values to the object is another thing I am probably doing wrong, so any advice there would be helpful as well. Thanks

Jack s
  • 1
  • 1
  • 1
    Does this answer your question? [How do you programmatically set an attribute?](https://stackoverflow.com/questions/285061/how-do-you-programmatically-set-an-attribute). Or [Python Class dynamic attribute access](https://stackoverflow.com/questions/34831505/python-class-dynamic-attribute-access) – wwii Jun 22 '20 at 22:20

2 Answers2

0

You can make use of the built-in functions getattr and setattr to interact with an object's attributes. Here is an example:

class Attributes(object):
    def __init__(self, strength, speed):
        self.strength = strength
        self.speed = speed

    def increase(self, attribute, amount):
        value = getattr(self, attribute)
        value += amount
        setattr(self, attribute, value)


you = Attributes(1, 2)
you.increase("strength", 5)
print(you.strength)  # outputs: 6
ibaira
  • 1
0

The placement of a variable declaration affects its scope. The strength parameter of the Attributes constructor __init__ has a local scope, which means that it is only visible from within the __init__ method. To learn more about scope see https://docs.python.org/3.3/reference/executionmodel.html.

Getting into the habit of using the setattr and getattr built-in functions would be considered bad practice, as explained here: Can the usage of `setattr` (and `getattr`) be considered as bad practice?.

In addition, the interface-segregation principle (ISP) of the SOLID design principles intended to make software designs more understandable, flexible and maintainable states that large interfaces should be split into smaller and more specific ones so that 'clients' only have to know about the methods that are of interest to them. ISP is intended to keep a system decoupled and thus easier to refactor, change, and redeploy. Therefore rather than writing one method responsible for increasing all properties, I would suggest splitting the method into smaller 'role interfaces' to improve code quality.

To this can be added that, as per the PEP 8 -- Style Guide for Python Code, variable names should be lowercase, with words separated by underscores as necessary to improve readability (https://www.python.org/dev/peps/pep-0008/). Furthermore, it is good practice to make type variables self-describing and cohesive.

To this end, I would suggest writing different methods for increasing strength and speed, changing the name of the Attributes class to something like Person and making the variable name You lowercase like so:

class Person(object):
    def __init__(self, strength, speed):
        self.strength = strength
        self.speed = speed
    
    def increaseStrength(self, amount):
        self.strength += amount

    def increaseSpeed(self, amount):
        self.speed += amount
   
you = Person(1, 2)


you.increaseStrength(5)

print(you.strength)