16.01.2014 Views

Beginning Python - From Novice to Professional

Beginning Python - From Novice to Professional

Beginning Python - From Novice to Professional

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

CHAPTER 9 ■ MAGIC METHODS, PROPERTIES, AND ITERATORS 183<br />

implemented (see the section “Emulating Container Types” in the <strong>Python</strong> Reference Manual,<br />

http://www.python.org/doc/ref/sequence-types.html), including the __iter__ method, which<br />

I describe in the section “Itera<strong>to</strong>rs,” later in this chapter. Implementing all these methods (<strong>to</strong><br />

make your objects fully polymorphically equivalent <strong>to</strong> lists or dictionaries) is a lot of work and hard<br />

<strong>to</strong> get right. If you want cus<strong>to</strong>m behavior in only one of the operations, it makes no sense that<br />

you should have <strong>to</strong> reimplement all of the others. It’s just programmer laziness (also called<br />

common sense).<br />

So what should you do? The magic word is “inheritance.” Why reimplement all of these<br />

things when you can inherit them? The standard library comes with three ready-<strong>to</strong>-use implementations<br />

of the sequence and mapping pro<strong>to</strong>cols (see the sidebar “UserList, UserString, and<br />

UserDict”), and in newer versions of <strong>Python</strong>, you can subclass the built-in types themselves.<br />

(Note that this is mainly useful if your class’s behavior is close <strong>to</strong> the default. If you have <strong>to</strong> reimplement<br />

most of the methods, it might be just as easy <strong>to</strong> write a new class.)<br />

USERLIST, USERSTRING, AND USERDICT<br />

The standard library contains three modules called UserList, UserString, and UserDict, each containing a<br />

class with the same name as the module. These classes satisfy all the requirements of the sequence and<br />

mapping pro<strong>to</strong>cols. UserList and UserString are cus<strong>to</strong>m sequences that behave just like ordinary lists and<br />

strings, while UserDict is a cus<strong>to</strong>m mapping that behaves just like ordinary dictionaries. Until <strong>Python</strong> 2.2, these<br />

were the best option as superclasses when creating your own mappings and sequences. In <strong>Python</strong> 2.2, the capability<br />

<strong>to</strong> subclass built-in types was added, making these less useful.<br />

So, if you want <strong>to</strong> implement a sequence type that behaves similarly <strong>to</strong> the built-in lists, you<br />

can simply subclass list.<br />

■Note When you subclass a built-in type such as list, you are indirectly subclassing object. Therefore your<br />

class is au<strong>to</strong>matically new-style, which means that such features as the super function are available.<br />

Let’s just do a quick example—a list with an access counter:<br />

class CounterList(list):<br />

def __init__(self, *args):<br />

super(CounterList, self).__init__(*args)<br />

self.counter = 0<br />

def __getitem__(self, index):<br />

self.counter += 1<br />

return super(CounterList, self).__getitem__(index)<br />

The CounterList class relies heavily on the behavior of its subclass (list). Any methods not<br />

overridden by CounterList (such as append, extend, index, and so on) may be used directly. In the<br />

two methods that are overridden, super is used <strong>to</strong> call the superclass version of the method, only

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!