Example 18-3. PP4E\Dstruct\Basic\stacklog.py
"customize stack for usage data"
from stack2 import Stack # extends imported Stack
class StackLog(Stack): # count pushes/pops, max-size
pushes = pops = 0 # shared/static class members
def init(self, start=[]): # could also be module vars
self.maxlen = 0
Stack.init(self, start)
def push(self, object):
Stack.push(self, object) # do real push
StackLog.pushes += 1 # overall stats
self.maxlen = max(self.maxlen, len(self)) # per-instance stats
def pop(self):
StackLog.pops += 1 # overall counts
return Stack.pop(self) # not 'self.pops': instance
def stats(self):
return self.maxlen, self.pushes, self.pops # get counts from instance
This subclass works the same as the original Stack; it just adds monitoring logic. The
new stats method is used to get a statistics tuple through an instance:
>>> from stacklog import StackLog
>>> x = StackLog()
>>> y = StackLog() # make two stack objects
>>> for i in range(3): x.push(i) # and push object on them
>>> for c in 'spam': y.push(c)
>>> x, y # run inherited __repr__
([Stack:[2, 1, 0]], [Stack:['m', 'a', 'p', 's']])
>>> x.stats(), y.stats()
((3, 7, 0), (4, 7, 0))
>>>
>>> y.pop(), x.pop()
('m', 2)
>>> x.stats(), y.stats() # my maxlen, all pushes, all pops
((3, 7, 2), (4, 7, 2))
Notice the use of class attributes to record overall pushes and pops, and instance at-
tributes for per-instance maximum length. By hanging attributes on different objects,
we can expand or narrow their scopes.
Optimization: Tuple Tree Stacks
One of the nice things about wrapping objects up in classes is that you are free to change
the underlying implementation without breaking the rest of your program. Optimiza-
tions can be added in the future, for instance, with minimal impact; the interface is
Implementing Stacks| 1367