Search code examples
pythonclassmethodsattributes

Can I modify an attribute by passing it as variable to a method? - python


So I have a class with an attribute, say a, and I want to be able to modify it by using a method but I want that method to be reusable with other attributes.

Example:

class My_Class():
    def __init__(self):
        self.a = 0
        self.b = 1
    def add_one(self, x):
        x = x + 1
    def add_to_all(self):
        self.add_one(self.a)
        self.add_one(self.b)

with the code above I would expect:

adder = My_Class()
print(adder.a)

# 0

adder.add_to_all()

print(adder.a)
#1

this is not working and I am wondering how can do what I intend.

ChaGPT suggests:

class My_Class():
    def __init__(self):
        self.a = 0
        self.b = 1
    def add_one(self, x):
        setattr(self, x, getattr(self, x) + 1)
    def add_two(self):
        self.add_one('a')
        self.add_one('b')

which works, but I might as well create two methods:

    def add_a(self):
        self.a = self.a + 1
    
    def add_b(self):
        self.b = self.b + 1

and would duplicate code but in my opinion it would be cleaner (this case only adds 1 to a variable but in my real problem there are many variables and complex operations in each method, a and b).

Any idea if there is another way to implement this or sugestion of which option to use (chatGPT or duplicate methods)?


Solution

  • In Python, ints are immutable. When you run x += 1, Python doesn't modify the value in memory that x is pointing to—it just points x to a different value.

    With that in mind, there are a couple of ways you can go about this implementation. The solution you got from ChatGPT is probably the most straightforward, but here's another way that works:

    class My_Class:
        def __init__(self):
            self.values = [0, 1]
    
        @property
        def a(self):
            return self.values[0]
    
        @property
        def b(self):
            return self.values[1]
    
        def add_to_all(self):
            self.values = [val + 1 for val in self.values]
    

    This also will accomplish what you're going for, although if you also want to be able to set the values for a & b (i.e. self.a = 3) you'll need to add setter methods as well.