8

I am using ipython and I want to save a class defined in one of my notebooks. I can do this with functions nicely with %save and inspect.getsource, but I cant seem to get the source of my class. I had a quick look at the methods in inspect and couldnt seem to find anything that could help. Any suggestions?

class A():
    def __init__(self):
        self.x = 1

%save filename.py inspect.getsource(A)

inspect.getsource(A)
>>> ...
>>> TypeError: <module '__main__'> is a built-in class
Thomas K
  • 39,200
  • 7
  • 84
  • 86
Alexander Telfar
  • 559
  • 1
  • 6
  • 7

1 Answers1

5

getsource works by actually opening the source file that defines the object you're looking at.

But, since you defined A in the interactive interpreter, there is no such source file, and therefore Python can't find one.

The error is somewhat obscure, but Python basically tries to look up the source file for A's module (A.__module__), which is __main__, and which has no __file__ property (because it didn't come from a file).

Thomas Orozco
  • 53,284
  • 11
  • 113
  • 116
  • 3
    Footnote: it does work for function definitions (try `inspect.getsource(A.__init__)`), because functions have a code object, and that refers to the file the function was defined in. IPython works with the linecache module to record each input as a 'file' for this purpose (and for tracebacks). But classes don't store a code object, so it has to refer to the module, and the `__main__` module is split up into separate chunks. – Thomas K Mar 07 '16 at 22:54
  • Ok, I get it thanks. Yea, it does work with the methods of a class, like init but I want the whole thing... Any other suggestions for a good way to use a class defined in one ipython notebook in another? – Alexander Telfar Mar 08 '16 at 19:25
  • 1
    I have come up with a cheap hack. Just define the class in a function and get it to return an instance of the class. But, surely there is a better way? – Alexander Telfar Mar 08 '16 at 19:31
  • OK, I found a way. You can use `ipython notebook --script` so that the ipnb is also saved as a script and the import the functions/classes from there, but you just have to suppress the outputs. I just used `if __name__ == '__main__':` to suppress the outputs. Maybe there is a better way? – Alexander Telfar Mar 08 '16 at 19:54