Setter and deleter properties

In the previous examples, we defined the card property to deal additional cards into an object of the Hand class.

Since setter (and deleter) properties are created from the getter property, we must always define a getter property first using the following code:

    @property
    def card( self ):
        return self._cards
    @card.setter
    def card( self, aCard ):
        self._cards.append( aCard )
    @card.deleter
    def card( self ):
        self._cards.pop(-1)

This allows us to add a card to the hand with a simple statement like the following:

h.card= d.pop()

The preceding assignment statement has a disadvantage because it looks like it replaces all the cards with a single card. On the other hand, it also has an advantage because it uses simple assignment to update the state of a mutable object. We can use the __iadd__() special method to do this a little more cleanly. But, we'll wait until Chapter 7, Creating Numbers, to introduce the other special methods.

For our current examples, there's no compelling reason to use a deleter property. Even without a compelling reason, there's still some use for a deleter. We could, however, make use of it to remove the last dealt card. This can be used as part of the process for splitting a hand.

We will consider a version of split() that works like the following code:

    def split( self, deck ):
        """Updates this hand and also returns the new hand."""
        assert self._cards[0].rank == self._cards[1].rank
        c1= self._cards[-1]
        del self.card
        self.card= deck.pop()
        h_new= self.__class__( self.dealer_card, c1, deck.pop() )
        return h_new

The preceding method updates the given hand and returns a new hand. The following is an example of a hand being split:

>>> d= Deck()
>>> c= d.pop()
>>> h= Hand_Lazy( d.pop(), c, c ) # Force splittable hand
>>> h2= h.split(d)
>>> print(h)
2♠, 10♠
>>> print(h2)
2♠, A♠

Once we have two cards, we can use split() to produce the second hand. A card was removed from the initial hand.

This version of split() is certainly workable. However, it seems somewhat better to have the split() method return two fresh new Hand objects. That way, the old, presplit Hand instance can be used as a memento to gather statistics.