Adding ipipe support

Automatically invoking an ipipe display for iterables

You can add support for ipipe to your own classes too. Anything that is iterable can be displayed by piping it into an ipipe enabled object, but if you want an ipipe display to automatically display your object, you have to subclass ipipe.Table and implement an __iter__ method. For example an ipipe enabled version of range might look like this:

   1 from IPython.Extensions import ipipe
   2 
   3 class irange(ipipe.Table):
   4     def __init__(self, *args):
   5         self.args = args
   6 
   7     def __iter__(self):
   8         return iter(xrange(*self.args))

If you want to implement a "filter" (i.e. something that transforms an input pipe), you have to subclass ipipe.Pipe. This gives you automatic handling of the | operator. In your __iter__ method you can access the input pipe as the input attribute. For example the following pipe will skip every second item:

   1 from IPython.Extensions import ipipe
   2 
   3 class ieven(ipipe.Pipe):
   4     def __iter__(self):
   5         for (i, item) in enumerate(self.input):
   6             if not i % 2:
   7                 yield item

Now you can user your new classes like this:

In   [1:] irange(100) | ieven

Specifying attributes for the ipipe display

You can specify which attributes should be displayed in an ipipe listing by implementing the __xattrs__ method:

   1 class Person:
   2     def __init__(self, firstname, lastname):
   3         self.firstname = firstname
   4         self.lastname = lastname
   5 
   6     def __xattrs__(self, mode="default"):
   7         return ("firstname", "lastname")

(If __xattrs__() isn't defined the ipipe display will simply use the repr() result for the object itself)

The mode attribute has two possible values:

__xattrs__() must return an iterable with "attribute descriptors". These attribute descriptors can be:

For example we can add contact information to the above Person class:

   1 class Person:
   2     def __init__(self, firstname, lastname):
   3         self.firstname = firstname
   4         self.lastname = lastname
   5         self.contacts = []
   6 
   7     def addcontact(self, type, value):
   8         self.contacts.append(Contact(type, value))
   9 
  10     def __xattrs__(self, mode="default"):
  11         if mode == "detail":
  12             return ("firstname", "lastname", "-contacts")
  13         else:
  14             return ("firstname", "lastname")
  15 
  16 class Contact:
  17     def __init__(self, type, value):
  18         self.type = type
  19         self.value = value
  20 
  21     def __xattrs__(self, mode="default"):
  22         return ("type", "value")
  23 
  24 p1 = Person("John", "Doe")
  25 p1.addcontact("email", "john@example.com")
  26 p1.addcontact("phone", "555-0123")
  27 
  28 p2 = Person("Jane", "Doe")
  29 p2.addcontact("email", "jane@example.com")
  30 p2.addcontact("phone", "555-0321")
  31 
  32 persons = [p1, p2]

With these objects you can then browse them like this:

In  [1]: persons | ibrowse

SupportingIPipe (last edited 2006-11-29 22:52:27 by dslb-088-065-215-040)