Mastering Objectoriented Python
上QQ阅读APP看书,第一时间看更新

Complete composite object initialization

Ideally, the __init__() initializer method will create a complete instance of an object. This is a bit more complex when creating a complete instance of a container that contains an internal collection of other objects. It'll be helpful if we can build this composite in a single step.

It's common to have both a method to incrementally accrete items as well as the initializer special method that can load all of the items in one step.

For example, we might have a class such as the following code snippet:

class Hand2:
    def __init__( self, dealer_card, *cards ):
        self.dealer_card= dealer_card
        self.cards = list(cards)
    def hard_total(self ):
        return sum(c.hard for c in self.cards)
    def soft_total(self ):
        return sum(c.soft for c in self.cards)

This initialization sets all of the instance variables in a single step. The other methods are simply copies of the previous class definition. We can build a Hand2 object in two ways. This first example loads one card at a time into a Hand2 object:

d = Deck()
P = Hand2( d.pop() )
p.cards.append( d.pop() )
p.cards.append( d.pop() )

This second example uses the *cards parameter to load a sequence of Cards class in a single step:

d = Deck()
h = Hand2( d.pop(), d.pop(), d.pop() )

For unit testing, it's often helpful to build a composite object in a single statement in this way. More importantly, some of the serialization techniques from the next part will benefit from a way of building a composite object in a single, simple evaluation.