Online Book Reader

Home Category

Learning Python - Mark Lutz [422]

By Root 1685 0

Beginning with Python 2.2, all the built-in types in the language can now be subclassed directly. Type-conversion functions such as list, str, dict, and tuple have become built-in type names—although transparent to your script, a type-conversion call (e.g., list('spam')) is now really an invocation of a type’s object constructor.

This change allows you to customize or extend the behavior of built-in types with user-defined class statements: simply subclass the new type names to customize them. Instances of your type subclasses can be used anywhere that the original built-in type can appear. For example, suppose you have trouble getting used to the fact that Python list offsets begin at 0 instead of 1. Not to worry—you can always code your own subclass that customizes this core behavior of lists. The file typesubclass.py shows how:

# Subclass built-in list type/class

# Map 1..N to 0..N-1; call back to built-in version.

class MyList(list):

def __getitem__(self, offset):

print('(indexing %s at %s)' % (self, offset))

return list.__getitem__(self, offset - 1)

if __name__ == '__main__':

print(list('abc'))

x = MyList('abc') # __init__ inherited from list

print(x) # __repr__ inherited from list

print(x[1]) # MyList.__getitem__

print(x[3]) # Customizes list superclass method

x.append('spam'); print(x) # Attributes from list superclass

x.reverse(); print(x)

In this file, the MyList subclass extends the built-in list’s __getitem__ indexing method only to map indexes 1 to N back to the required 0 to N−1. All it really does is decrement the submitted index and call back to the superclass’s version of indexing, but it’s enough to do the trick:

% python typesubclass.py

['a', 'b', 'c']

['a', 'b', 'c']

(indexing ['a', 'b', 'c'] at 1)

a

(indexing ['a', 'b', 'c'] at 3)

c

['a', 'b', 'c', 'spam']

['spam', 'c', 'b', 'a']

This output also includes tracing text the class prints on indexing. Of course, whether changing indexing this way is a good idea in general is another issue—users of your MyList class may very well be confused by such a core departure from Python sequence behavior. The ability to customize built-in types this way can be a powerful asset, though.

For instance, this coding pattern gives rise to an alternative way to code a set—as a subclass of the built-in list type, rather than a standalone class that manages an embedded list object, as shown earlier in this section. As we learned in Chapter 5, Python today comes with a powerful built-in set object, along with literal and comprehension syntax for making new sets. Coding one yourself, though, is still a great way to learn about type subclassing in general.

The following class, coded in the file setsubclass.py, customizes lists to add just methods and operators related to set processing. Because all other behavior is inherited from the built-in list superclass, this makes for a shorter and simpler alternative:

class Set(list):

def __init__(self, value = []): # Constructor

list.__init__([]) # Customizes list

self.concat(value) # Copies mutable defaults

def intersect(self, other): # other is any sequence

res = [] # self is the subject

for x in self:

if x in other: # Pick common items

res.append(x)

return Set(res) # Return a new Set

def union(self, other): # other is any sequence

res = Set(self) # Copy me and my list

res.concat(other)

return res

def concat(self, value): # value: list, Set . . .

for x in value: # Removes duplicates

if not x in self:

self.append(x)

def __and__(self, other): return self.intersect(other)

def __or__(self, other): return self.union(other)

def __repr__(self): return 'Set:' + list.__repr__(self)

if __name__ == '__main__':

x = Set([1,3,5,7])

y = Set([2,1,4,5,6])

print(x, y, len(x))

print(x.intersect(y), y.union(x))

print(x & y, x | y)

x.reverse(); print(x)

Here is the output of the self-test code at the end of this file. Because subclassing core types is an advanced feature, I’ll omit further details here, but I invite you to trace through these results in the code to study

Return Main Page Previous Page Next Page

®Online Book Reader