0

Is it possible to set a property with shorthand operators like +=, or -=?

I've read this post, What's the pythonic way to use getters and setters?, but it deals mainly with direct assignment in terms of object.attr = value. When thinking about it, I'm finding it difficult to be possible and I've never used setters so I'm not sure.

It is within the Player.hit() method where I'm attempting to achieve this where I'm subtracting and integer reduced_points from another integer value property:

self.hands[x].value -= reduced_points

NOTE: Hand.value is an @property due to that I need to dynamically add the values of each card in case a card is added to that hand.

class Card:
    def __init__(self, pip, suit, *args, **kwargs):
        self.pip = pip
        self.suit = suit
        if kwargs and 'face_card' in kwargs:
            self.face_card = kwargs['face_card']


class Hand:
    def __init__(self, cards):
        self.cards = cards # [Card(), Card(), Card()]
        self._value = sum(card.pip for card in cards)
    
    @property
    def soft(self):
        return any(
            hasattr(card, 'face_card') and
            card.face_card == "Ace" for card in self.cards
        )

    @property
    def value(self):
        return sum([card.pip for card in self.cards])

    @value.setter
    def set_value(self, value):
        new_value = self._value - value
        self._value = new_value

class Player:

    def __init__(self):
        self.name = "Player"
        self.hands = []
        self.chips = 0
        self._bet = 0

    def hit(self, hand):
        if hand.soft:
            x, hand = list(filter(
                lambda h: h[1].soft, enumerate(self.hands)
            ))[0]
            total_aces = len(
                list(
                    filter(lambda c: hasattr(c, 'face_card') and
                    c.face_card == "Ace", self.hands[x].cards)
                )
            )
            reduced_points = 10 * (total_aces - 1)
            self.hands[x].value -= reduced_points
            if self.hands[x].value > 21:
                return self.hands[x], "BUST"
        if hand.value > 21:
            return hand , "BUST"
        return hand, "HIT"
binny
  • 649
  • 1
  • 8
  • 22
  • Your setter makes no sense. Even if you fixed the name bug, you've implemented it in such a way that `hand.value = 5` *reduces* the value by 5 instead of setting the value to 5. – user2357112 Dec 15 '20 at 02:39

1 Answers1

0

When creating a property setter, it needs to have the same name as the getter. So both the getter and setter needed to be def value(...). But yes, hand.value -= 3 should do exactly what you expect it to.

user2357112
  • 260,549
  • 28
  • 431
  • 505
Frank Yellin
  • 9,127
  • 1
  • 12
  • 22
  • The setter body makes no sense, so `hand.value -= 3` is going to do something completely different from reducing the value by 3. – user2357112 Dec 15 '20 at 02:40
  • I don't understand. Python interprets `foo.value -= 3` as `foo.value = foo.value - 3`. (Except that if `foo` is only evaluated once.). Why is this unexpected? – Frank Yellin Dec 15 '20 at 14:36
  • That part is fine, but assigning to `foo.value` doesn't actually set the value to whatever you assigned, even with the setter name bug fixed. Look at what the setter is doing - it interprets `foo.value = whatever` as `foo._value -= whatever`. – user2357112 Dec 15 '20 at 17:56
  • I wasn't commenting on the poster's code. They asked whether `+=` or `-=` worked, and I responded in the affirmative. I wasn't asked to--and didn't bother to--check if the code in question was doing the right thing. – Frank Yellin Dec 15 '20 at 18:21