Extending Built-in Types

Extending Types by Embedding

  • The set functions can be brought back to life as a Python class. The following example implements a new set object type by moving some of the set functions to methods and by adding some basic operator overloading.
class Set:
    def __init__(self, value = []): # Constructor
            self.data = [] # Manages a list
            self.concat(value)

    def intersect(self, other): # other is any sequence
            res = [] # self is the subject
            for x in self.data:
                    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 = self.data[:] # Copy of my list
                    for x in other: # Add items in other
                            if not x in res:
                                    res.append(x)
                    return Set(res)

    def concat(self, value): # value: list, Set...
            for x in value: # Removes duplicates
                    if not x in self.data:
                            self.data.append(x)

    def __len__(self): return len(self.data) # len(self), if self
    def __getitem__(self, key): return self.data[key] # self[i], self[i:j]
    def __and__(self, other): return self.intersect(other) # self & other
    def __or__(self, other): return self.union(other) # self | other
    def __repr__(self): return 'Set:' + repr(self.data) # print(self),...
    def __iter__(self): return iter(self.data) # for x in self,...

To use this class, we make instances, call methods, and run defined operators as usual: .. code-block:: python

from setwrapper import Set
x = Set([1, 3, 5, 7]) print(x.union(Set([1, 4, 7]))) # prints Set:[1, 3, 5, 7, 4] print(x | Set([1, 4, 6])) # prints Set:[1, 3, 5, 7, 4, 6]

Overloading operations such as indexing and iteration also enable instances of the Set class to often masquerade as real lists.

Extending Types by Subclassing

  • 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 one to customize or extend the behavior of built-in types with userdefined class statements: simply subclass the new type names to customize them.
  • Instances of your type subclasses can generally be used anywhere that the original builtin type can appear.

Consider the Example:

# 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)