krishnab
krishnab

Reputation: 10060

python classes: class attributes don't update when accessed through a list

I am running into some odd behavior with a python class, and I was hoping someone might be able to explain the cause and fix. I am using python 3.8.5. The problem is that when I have a list of class attributes and I try and update them, that they don't seem to get updated. Here is a simple example.

class testclass:
    def __init__(self) -> None:
        self.a = 2
        self.b = 3
        self.c = 4

    def update(self):
        for s in [self.a, self.b, self.c]:
            s = 10

    def response(self):
        self.update()
        print([self.a, self.b, self.c])


if __name__ == '__main__':
    myclass = testclass()
    myclass.response()

The output that I get is [2, 3, 4], when it should be [10,10,10] after the update() method is applied, right? Is there a better way to do something like this?

Upvotes: 0

Views: 63

Answers (1)

Brad Solomon
Brad Solomon

Reputation: 40878

When you iterate over the list [self.a, self.b, self.c], each s is effectively a copy of that element.

This can be boiled down more simply to get rid of the class and self stuff:

>>> f = [1, 2, 3]
>>> for s in f:
...     # s is implicitly assigned s=1, s=2, s=3
...     s = 10
... 
>>> f
[1, 2, 3]

Is there a better way to do something like this?

Depends what you really want to do here, since this example seems somewhat contrived. In general try to avoid modifying a list while iterating over it.

Let's assume your goal is to set each self.XXX to an arbitrary int. Here's a Pythonic way you can do that:

self.a = self.b = self.c = 10

Make sure to only use this trick with immutable data, such as the int 10. If you were to chain-assign to a list, for instance, future assignments would also mutate the other attributes besides the one you're acting on.

Upvotes: 2

Related Questions