How to execute more than one cell together

I have a class definition that I want to put in my first cell:

class MyObj:
def init(self, s):
self.s = s

def __repr__(self):
    return '<MyObj({})>'.format(self.s)

Then I have many other cells that refer to the above class. How do I make Jupyter Lab execute the above cell and another cell?

Also, the MyObj class is in a file named json_myobj.py and the other code file starts with:

import json_myobj

How do you do the equivalent thing in Jupiter Lab?

JupyterLab’s ‘Run’ menu has an option that says run ‘All above selected cell’.

If you set the file json_myobj alongside the notebook file, you should just be able to import it with import json_myobj executed in a cell in the running .ipynb file. It doesn’t matter what Jupyter interface you are using. That import should work. You can check after with dir().

Yes, that did work to put the class definition in a separate file named json_myobj.py.
Another related question…

I am able to select adjacent cells using the SHIFT key.

But if I try to select non-adjacent cells using the CTRL button the first cell selected always gets unselected.

Now when I run a cell that references class MyObj I can see in the debugger it is stepping through the external file json_myobj.py, but when continuing back in the original cell it does not recognize that MyObj is defined.

I thought you could only select a contiguous span of cells in JupyterLab?

I don’t know how you are instantiating your object? It would be the instance of the object of that class type that is defined. What do you get with type(<instance_name>) after invoking the class instance?

Here is the cell:

import json
import json_myobj

print(type(MyObj)) # MyObj not defined error

obj = MyObj(‘instance value goes here’)
print(‘First attempt’)
try:
print(json.dumps(obj))
except TypeError as err:
print(‘ERROR:’, err)

def convert_to_builtin_type(obj):
print(‘default(’, repr(obj), ‘)’)
# Convert objects to a dictionary of their representation
d = {
class’: obj.class.name,
module’: obj.module,
}
d.update(obj.dict)
return d

print()
print(‘With default’)
print(json.dumps(obj, default=convert_to_builtin_type))

Here is the file json_myobj.py:

class MyObj:

def __init__(self, s):
    self.s = s

def __repr__(self):
    return '<MyObj({})>'.format(self.s)

But if I run this cell it works fine:

import json
import json_myobj

class MyEncoder(json.JSONEncoder):

def default(self, obj):
    print('default(', repr(obj), ')')
    # Converts objects to a dictionary of their representation
    d = {
        '__class__': obj.__class__.__name__,
        '__module__': obj.__module__,
    }
    d.update(obj.__dict__)
    return d

obj = json_myobj.MyObj(‘internal data’)
print(obj)
print(MyEncoder().encode(obj))

I made the following change which solved the problem:

obj = MyObj(‘instance value goes here’)

was changed to:

obj = json_myobj.MyObj(‘instance value goes here’)

I noticed in the debugger when you step into “import json_myobj”
it steps through only these lines of the file:
class MyObj:
def init(self,s)
def repr(self)

What is actually happening when it runs those 3 lines? When Python continues it “knows” about the class name and the class methods but nothing has been instantiated.

Yes, you would have wanted to import differently to use MyObj.

Like so,

from module import fun1
import json
from json_myobj import MyObj

obj = MyObj(‘instance value goes here’)

I think that option also works and doesn’t mean you need to use attribute access notation , the dot notation stuff, like module_name.attribute_name.

I thought of the fact you may be forgetting to add the json_myobj. part in front of the class later and didn’t get back to write that before you figured it out. These are Python issues though and independent of Jupyter as you’d have the same problem if you weren’t running your main namespace in a Jupyte notebook file and were instead running python in the interpreter/console or as a traditional python script you invoke on the command line.