[Python编程(第4版)].(Programming.Python.4th.Edition).Mark.Lutz.文字版

(yzsuai) #1

Like lists and dictionaries, Stack defines both methods and operators for manipulating
instances by attribute references and expressions. Additionally, it defines the get
attr
special method to intercept references to attributes not defined in the class and
to route them to the wrapped list object (to support list methods: sort, append,
reverse, and so on). Many of the module’s operations become operators in the class.
Table 18-3 shows the equivalence of module and class operations (columns 1 and 2)
and gives the class method that comes into play for each (column 3).


Table 18-3. Module/class operation comparison


Module operations Class operations Class method
module.empty() not instance __len__
module.member(x) x in instance __getitem__
module.item(i) instance[i] __getitem__
module.length() len(instance) __len__
module.dump() print(instance) __repr__
range() counter loops for x in instance __getitem__
manual loop logic instance + instance __add__
module.stack.reverse() instance.reverse() __getattr__
module.push/pop/top instance.push/pop/top push/pop/top

In effect, classes let us extend Python’s set of built-in types with reusable types imple-
mented in Python modules. Class-based types may be used just like built-in types:
depending on which operation methods they define, classes can implement numbers,
mappings, and sequences, and may or may not be mutable. Class-based types may also
fall somewhere in between these categories.


Customization: Performance Monitors


So far we’ve seen how classes support multiple instances and integrate better with
Python’s object model by defining operator methods. One of the other main reasons
for using classes is to allow for future extensions and customizations. By implementing
stacks with a class, we can later add subclasses that specialize the implementation for
new demands. In fact, this is often the main reason for using a custom class instead of
a built-in alternative.


For instance, suppose we’ve started using the Stack class in Example 18-2, but we start
running into performance problems. One way to isolate bottlenecks is to instrument
data structures with logic that keeps track of usage statistics, which we can analyze
after running client applications. Because Stack is a class, we can add such logic in a
new subclass without affecting the original stack module (or its clients). The subclass
in Example 18-3 extends Stack to keep track of overall push/pop usage frequencies and
to record the maximum size of each instance.


1366 | Chapter 18: Data Structures

Free download pdf