Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Define a Python class across multiple cells #1243

Closed
Carreau opened this issue Mar 22, 2016 · 18 comments

Comments

@Carreau
Copy link
Contributor

commented Mar 22, 2016

This issue is both Notebook & IPython, but I guess could be solved here only with an extension.

Again, requested during JupyterDays:

For education purpose, it would be nice to be able to define a class across many cells., in particular 1 method/cell.

I think it is possible by peeking at next/previous coed cells, and if the all body of a cell is indented by at least 4 spaces, "join" the content of each cell before sending a single execution request.

we could "mark" joined executed cells with a specific prompt.

Ping @ellisonbg

@ellisonbg

This comment has been minimized.

Copy link
Contributor

commented Mar 23, 2016

Could you edit the title of this issue - at first I thought you were
talking about CSS classes or something in the UI. Maybe something like
"Define a Python class across multiple cells?"

On Tue, Mar 22, 2016 at 11:56 AM, Matthias Bussonnier <
notifications@github.com> wrote:

This issue is both Notebook & IPython, but I guess could be solved here
only with an extension.

Again, requested during JupyterDays:

For education purpose, it would be nice to be able to define a class
across many cells., in particular 1 method/cell.

I think it is possible by peeking at next/previous coed cells, and if the
all body of a cell is indented by at least 4 spaces, "join" the content of
each cell before sending a single execution request.

we could "mark" joined executed cells with a specific prompt.

Ping @ellisonbg https://github.com/ellisonbg


You are receiving this because you were mentioned.
Reply to this email directly or view it on GitHub
#1243

Brian E. Granger
Associate Professor of Physics and Data Science
Cal Poly State University, San Luis Obispo
@ellisonbg on Twitter and GitHub
bgranger@calpoly.edu and ellisonbg@gmail.com

@Carreau Carreau changed the title write a class across many cells. Define a Python class across multiple cells Mar 23, 2016

@Carreau

This comment has been minimized.

Copy link
Contributor Author

commented Mar 23, 2016

Title updated.

@takluyver

This comment has been minimized.

Copy link
Member

commented Mar 23, 2016

We currently dedent code if it's all indented, because it's not uncommon to copy some code from the middle of a method or function with the intention of running it directly.

I'm happy to help someone build an extension for this, but:

  • I don't think it's likely to be smooth or seamless enough to go into IPython/Jupyter itself
  • I'd probably do it with cell magics, e.g. %%addtoclass FooBar. Explicit is better than implicit, etc.
@Carreau

This comment has been minimized.

Copy link
Contributor Author

commented Mar 23, 2016

We dedent it in IPython, I'm thinking a Js extension can likely handle submitting all cells at the same time.

@takluyver

This comment has been minimized.

Copy link
Member

commented Mar 23, 2016

I'm not quite sure what you're envisaging, but I can't see anything in the frontend solving this in a nice way.

@minrk

This comment has been minimized.

Copy link
Member

commented Mar 23, 2016

js can group the cells input and send it as a single execution, rather than executing the cells separately.

@Carreau

This comment has been minimized.

Copy link
Contributor Author

commented Mar 23, 2016

Cell.prototype.execute = function(){
   if(this.all_indented){
      this.kernel.execute(this.previous.cell.source + this.cell.source)
   } else {
      this.kernel.execute(this.cell.source)
  }
}
@takluyver

This comment has been minimized.

Copy link
Member

commented Mar 23, 2016

That feels like something that could be really confusing, so I wouldn't want it on by default. But if it's an optional extension, then it's very easy for people using it to create notebooks that won't work for anyone without the extension, and will fail in mysterious and confusing ways.

@Carreau

This comment has been minimized.

Copy link
Contributor Author

commented Mar 23, 2016

That feels like something that could be really confusing, so I wouldn't want it on by default. But if it's an optional extension, then it's very easy for people using it to create notebooks that won't work for anyone without the extension, and will fail in mysterious and confusing ways.

Yep, seem about right.

@Carreau Carreau modified the milestone: wishlist Jun 28, 2016

@Henry-E

This comment has been minimized.

Copy link

commented Nov 30, 2016

An explicit cell magics for this would be nice

@aaronmyatt

This comment has been minimized.

Copy link

commented Dec 3, 2016

My humble vision for this sort of feature is the ability to create 'subcells'. Perhaps even automatically convert doc strings and other inline comments into these 'subcells'. Therefore we could conveniently intersperse markdown within classes and other long code blocks where appropriate. The challenge, I suspect, will be executing the 'parent' cell as a single unit.

I am trawling the documentation now to prepare myself for contributing plugins/fixes. However, if someone can kindly point me in the right direction I will gladly take a stab at implementing this. What is the feasibility of my suggestion? Would it need to be a plugin?

@alexhagen

This comment has been minimized.

Copy link

commented May 15, 2017

I made a magic for this exact purpose, I'm calling it jdc - or Jupyter dynamic classes. It's super simple, but basically it allows you to type

%%add_to our_class
def our_method(self, our_variable):
    print our_variable

and that method will be added to the class our_class (and all objects of that type) with access to self. You can also add it to only a single object with

%%add_to our_object
def our_method(self, our_variable):
    print our_variable

Documentation is at https://alexhagen.github.io/jdc. I hope this helps

@jasongrout

This comment has been minimized.

Copy link
Member

commented Sep 29, 2017

@alexhagen - @jzf2101 just pointed out your solution to this issue. Solving this with a package like yours looks like a great solution to this issue. Do you plan to release this as a python package on pypi?

I think this issue can be closed as solved with this package. @Carreau - what do you think?

@alexhagen

This comment has been minimized.

Copy link

commented Oct 2, 2017

I've put it up on PyPI. Should install via

pip install jdc

Tested on Ubuntu with Python 2.7 and 3.3.

@jzf2101

This comment has been minimized.

Copy link
Contributor

commented Mar 1, 2018

@gnestor Is this issue still open?

@takluyver

This comment has been minimized.

Copy link
Member

commented Mar 1, 2018

i'd say that @alexhagen's jdc package is as 'solved' as this is going to get, so we should close this issue.

@jzf2101 jzf2101 closed this Mar 1, 2018

@dsblank

This comment has been minimized.

Copy link
Member

commented Mar 1, 2018

Just to point out that you can do this in regular Python, without resorting to any extra magic:

Cell 1:

class MyClass():
    def method1(self):
        print("method1")

Cell 2:

class MyClass(MyClass):
    def method2(self):
        print("method2")

Cell 3:

instance = MyClass()
instance.method1()
instance.method2()

That is, you can define a class recursively, cell by cell. I don't think the final class is any different from one defined all in one cell. So you don't need an extra package to "solve" this problem.

@syockit

This comment has been minimized.

Copy link

commented Nov 30, 2018

That is, you can define a class recursively, cell by cell. I don't think the final class is any different from one defined all in one cell. So you don't need an extra package to "solve" this problem.

Under the hood, this creates a hierarchy of classes with the same name.

import inspect
inspect.getmro(MyClass)
(__main__.MyClass, __main__.MyClass, object)

I don't know if there's a limit to the number of superclasses, but for a typical notebook it shouldn't be a problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
You can’t perform that action at this time.