tags:

views:

93

answers:

4

Hi, I am wondering a good way to follow if i would like to redefine the members of a previous defined class in ipython. say : I have defined a class intro like below, and later i want to redefine part of the function definition _print_api. Any way to do that without retyping it .

class intro(object):
   def _print_api(self,obj):
           def _print(key):
                   if key.startswith('_'):
                           return ''
                   value = getattr(obj,key)
                   if not hasattr(value,im_func):
                           doc = type(valuee).__name__
                   else:
                           if value.__doc__ is None:
                                   doc = 'no docstring'
                           else:
                                   doc = value.__doc__
                   return '        %s      :%s' %(key,doc)
                   res = [_print(element) for element in dir(obj)]
                   return '\n'.join([element for element in res if element != ''])
   def __get__(self,instance,klass):
           if instance is not None:
                   return self._print(instance)
           else:
                   return self._print_api(klass)
A: 

There isn't really a "good" way to do it. The best you can do is something like this:

# class defined as normally above, but now you want to change a funciton
def new_print_api(self, obj):
    # redefine the function (have to rewrite it)
    ...
# now set that function as the _print_api function in the intro class
intro._print_api = new_print_api

This will work even if you already have intro objects defined (that is, when you call introObject._print_api on an object that was already created it will call the new function you set). Unfortunately, you still have to redefine the function, but at least you don't have to rewrite the whole class.

Depending on your use-case, the best thing to do may be to have it in a separate module. import the class and, when you need to change something, just use the reload() function. However, this will not affect previous instances of the class (this may or may not be what you want).

Daniel G
A: 

When you get to the point where you've got that much code, it's easiest just to put it into a file and import that particular module. Then when you need to update, you can edit the file and re-run the import statement and you'll get the updated code, though previously defined objects will not get the updates.

Daniel DiPaolo
To get the updated code, you actually have to use the `reload(modulename)` function - running `import` again will have no effect (I believe the reason for this is so that if a large program imports the same thing in multiple possible locations it doesn't incur a big performance penalty).
Daniel G
A: 

If you use the IPython %edit features, you can use something like this

Unode
+4  A: 

Use the %edit command, or its alias %ed. Assuming that the intro class already exists in the ipython namespace, typing %ed intro will open an external editor on the source code for the class. When you save and exit the editor the code will be executed by ipython, effectively redefining the class.

The downside of this is that any instances that already exist will still be bound to the old version of the class - if this is an issue then you need to either recreate the objects or re-assign the obj.class attribute to point to the new version of the class.

You can also use %ed on modules, files and previous input lines, e.g. %ed 5 10:13 16 will create and edit a file composed of ipython input lines 5,10,11,12,13,16.

Dave Kirby
Really nice tip! Loving iPython more an more..
Victor Farazdagi