- Mastering Objectoriented Python
- Steven F. Lott
- 371字
- 2021-11-12 16:25:12
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.