IPYTHON AND CLEPY HAVE VERY LITTLE IN COMMON Matt Wilson CLEPY 2008 IPYTHON Supports tab-completion: In [2]: mu.a mu.as_xml mu.attrsearch You can (usually) see the source for an object like this: In [2]: mu.attrsearch?? Type: function Base Class: String Form: Namespace: Interactive File: /home/matt/lib/python/matt_utils.py Definition: mu.attrsearch(o, attr_substr, r=None) Source: def attrsearch(o, attr_substr, r=None): """ Return a list of any attributes of object o that have attr_substr in the name. o is any object that supports dir. attr_substr is a string. """ if not r: return [a for a in dir(o) if attr_substr.lower() in a.lower()] else: return [a for a in dir(o) if attr_substr.lower() in a.lower()] Every expression you type is stored in a dictionary In and the results are stored in Out: In [20]: In[8] Out[20]: u'1 + 1\n' In [21]: Out[8] Out[21]: 2 The %ed magic command has some neat tricks: %ed # opens a temporary file. %ed ~/foo.py # opens or creates foo.py %ed mu.attrsearch # opens the file where mu is defined in $EDITOR at the right line. %ed -p # opens the last file you just opened. %ed 8:10 14 # opens a new temporary file with what you put in on lines 8 through 10 and 14. doctest mode is helpful: In [42]: chunkify?? Type: function Base Class: String Form: Namespace: Interactive File: /home/matt/lib/python/matt_utils.py Definition: chunkify(s, chunksize) Source: def chunkify(s, chunksize): "Yield sequence s in chunks of size chunksize." for i in range(0, len(s), chunksize): yield s[i:i+chunksize] In [43]: %doctest_mode Exception reporting mode: Plain Doctest mode is: ON >>> import matt_utils as mu >>> list(mu.chunkify('abcdefghi', 3)) ['abc', 'def', 'ghi'] >>> %doctest_mode Exception reporting mode: Context Doctest mode is: OFF In [50]: %ed mu.chunkify # paste in the docstring. In [51]: reload(mu) Out[51]: In [52]: mu.chunkify?? def chunkify(s, chunksize): """ Yield sequence s in chunks of size chunksize. >>> import matt_utils as mu >>> list(mu.chunkify('abcdefghij', 3)) ['abc', 'def', 'ghi', 'j'] """ for i in range(0, len(s), chunksize): yield s[i:i+chunksize] In [65]: doctest.testmod(mu) ### SNIPPED OUT LOTS OF NOISE #### Out[65]: (0, 5) Also, the pdb integration is really nice: In [67]: %pdb Automatic pdb calling has been turned ON In [68]: mu.chunkify(66, 2) Out[68]: In [69]: list(_68) --------------------------------------------------------------------------- TypeError Traceback (most recent call last) /home/matt/svn-checkouts/ in () /home/matt/lib/python/matt_utils.py in chunkify(s, chunksize) 140 141 """ --> 142 for i in range(0, len(s), chunksize): 143 yield s[i:i+chunksize] 144 TypeError: object of type 'int' has no len() > /home/matt/lib/python/matt_utils.py(142)chunkify() 141 """ --> 142 for i in range(0, len(s), chunksize): 143 yield s[i:i+chunksize] ipdb> l 137 138 >>> list(mu.chunkify('abcdefghij', 3)) 139 ['abc', 'def', 'ghi', 'j'] 140 141 """ --> 142 for i in range(0, len(s), chunksize): 143 yield s[i:i+chunksize] 144 145 146 def as_xml(y, requestid=None, is_the_parent=True): 147 ipdb> a s = 66 chunksize = 2 ipdb> And if you forgot to turn on %pdb in advance, you can also use %debug after the fact. ipdb> q In [70]: %debug > /home/matt/lib/python/matt_utils.py(142)chunkify() 141 """ --> 142 for i in range(0, len(s), chunksize): 143 yield s[i:i+chunksize] ipdb> If you do this, then you'll always get an IPython session: $ cat ~/.pythonstartup import IPython IPython.Shell.IPShell().mainloop(sys_exit=1) Finally, there's lots more cool stuff in IPython. And IPython1 apparently is gonna be more like emacs SLIME where the editor and the python interpreter talk to each other over the network. So, you can attach to a multi-threaded app while it is running and tinker with it.