The 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 code that looks like the following example:

@property
def card(self) -> List[BlackJackCard]:
return self._cards

@card.setter
def card(self, aCard: BlackJackCard) -> None:
self._cards.append(aCard)

@card.deleter
def card(self) -> None:
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 has an advantage in that 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. However, we shall wait until Chapter 8, Creating Numbers, to introduce the other special methods.

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

def split(self, deck: Deck) -> "Hand":
"""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 instance and returns a new Hand object. Because this method is inside the Hand class definition, it must show the class name as a string because the class has not been fully defined yet.

The del statement will remove the last card from the current hand. This will use the @card.deleter property to do the work of deleting the card. For a lazy hand, nothing more needs to be done. For an eager hand, the totals must be updated. The assignment statement in front of the del statement was used to save the last card into a local variable, c1

The following is an example of a hand being split:

>>> d = Deck() 
>>> c = d.pop() 
>>> h = Hand_Lazy(d.pop(), c, c)  # Create a 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 to create the resulting 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, pre-split Hand instance can be saved as a memento for auditing or statistical analysis.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset