Reputation: 557
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)
Upvotes: 19
Views: 8662
Reputation: 13526
This answer is utilizing the editor.
If you're using Vim as editor,
for ipython
on Linux
, Vim is my default editor.
I'd ed
in ipython, then open the editing history,
and have the easy to find the last one to edit.
As mentioned by others, it's not convenient to specify which piece of codes that edit
should start with. I recall ed
once could open class definition by name, but it can't recently for me.
Hope this help # use editor's history
Upvotes: 0
Reputation: 21
I ran into problems using %edit
magic for classes and got the same kind of error mentioned in previous comments:
WARNING: The file 'None' where '<class '__main__.intro'>' was defined cannot be read.
If you do %edit intro._print_api
(or any other method in your class) you can work around the issue and edit the class definition, since the function you are editing is defined within the class definition, you get the full class in your $EDITOR
.
Unfortunately, I don't have enough reputation to comment, so I had to post as a new answer. Sorry about that, but I hope this help someone! :D
Upvotes: 0
Reputation: 9591
If you use the IPython %edit features, you can use something like this
Upvotes: 7
Reputation: 26552
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.
Upvotes: 13
Reputation: 69672
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).
Upvotes: 0
Reputation: 56390
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.
Upvotes: -1