0

I'm new to OOP and having difficulty to understand mutability of class characteristics in Python. For example:

class Table:
    def __init__(self, n_players):
        self.n_players = n_players
        self.hand_count = 0

    def update_hand_count(self):
        self.hand_count = self.hand_count + 1
        return

    def alternative_approach(self):
        hand_count = self.hand_count
        hand_count += 1

Can I be expected for both of these approaches to work reliably? I see that some types are immutable. So if I defined self.hand_count as int(0), would this impact the result?

Unfortunately my code example is too complex to copy here (and I'm not even sure what it driving my issue). All I know is that I am seeing scope type errors emerge where I am reassigning values in my object instance, but I don't understand OOP / class structures in Python well enough to get myself out of trouble.

James
  • 32,991
  • 4
  • 47
  • 70
C. Cooney
  • 471
  • 5
  • 19
  • 2
    `alternative_approach` simply doesn't work - you're only incrementing a local variable, you're doing nothing to change `self.hand_count`. – jasonharper Sep 03 '21 at 21:36
  • 1
    In `alternative_approach`, `self.hand_count` **is not updated at all**. Why do you think it would be? `int` objects are immutable. `hand_count += 1` creates a new int object and assigns it to the local variable `hand_count`. This is discarded when the method terminates. In your orignal function, `self.hand_count = self.hand_count + 1` *also* creates a new `int` object but it is assigned to the attribute `self.hand_count`... – juanpa.arrivillaga Sep 03 '21 at 21:37
  • I had thought that objects were memory references. So an assignment would still access the object. I’ve used this approach because the self…. references are complex and extend my code. I thought that using local assignments would still function against instances (ie it was not making a copy of the original value). Thank you for your comments. – C. Cooney Sep 03 '21 at 21:42
  • 1
    @C.Cooney **it definitely is not making a copy**. No copies are being made. `hand_count = self.hand_count` does not make a copy. The problem is that `int` objects are *immutable*, you *can't change an int object*. So the reference to the `int` object in `self.hand_count` will not be affected by anything you ever do to `hand_count` – juanpa.arrivillaga Sep 03 '21 at 21:43
  • 2
    Have a quick guide to what assignment actually means in Python: https://nedbatchelder.com/text/names.html – user2357112 Sep 03 '21 at 21:45
  • To implement `hand_count += 1`, the first attempt is `hand_count = hand_count.__iadd__(1)`. But `int.__iadd__` isn't defined, so it falls back to `hand_count = hand_count.__add__(1)`. Types that implement `__iadd__` typically return `self` so that the original object is assigned back to the name. – chepner Sep 03 '21 at 21:59

0 Answers0