Can I create multiple __name__=="__main__" inside same jupyter notebook?

Viewed 72

I have a .ipynb jupyter notebook file, where I am working. The file contains multiple classes and methods. Some of them are dependent while some of them are not. For example:

class Node:
    ## this is where I create a single node

class LinkedList:
    ## this is where I create linked list

After this, I create another class where I inherit my base classes and implement algorithms.

class Solution:
    ## this is where I implement my algorithm

    method1():
        # method1 implementation
    
    method2():
        # method2 implementation

Finally, I create multiple mains in different cells below.

## main1 -- test case #1
if __name__ == "__main__":
   ## declare variables
   ## call classes and methods
   ## print something

In the next cell, I would do the following.

## main2 -- test case #2
if __name__ == "__main__":
   ## declare variables
   ## call classes and methods
   ## print something

Similarly, I would do this in next cell.

## main3 -- test case #3
if __name__ == "__main__":
   ## declare variables 
   ## call classes and methods
   ## print something

I like this template while solving leetcode problems locally. But I think while debugging, it's a little bit confusing.

Is it a standard practice to do so in the jupyter notebook working environment? Does it mess up with scopes? Please help me understand if it a good practice, or recommend me how to run multiple test cases within the same jupyter notebook. Thank you so much for reading this far.

1 Answers

Ummm, that's a little weird.

You have the right idea, wanting to keep things separate. Just do it a bit differently, use function definitions to accomplish your goal:

def main1():
    ...

def main2():
    ...

def main3():
    ...

main1()
main2()
main3()

Background: why do we use that __main__ idiom at all?

Well, it originated long before Jupyter notebooks appeared on the scene.

A developer working on def foo(): will want to run it during testing, and will commonly make the last lines of foo.py look like:

if __name__ == '__main__':
    print('result was', foo())

Now, we could create a foo_test.py file, but often the above will be most convenient.

Why not just a single-line call of foo()? We protect the call for safe import by other modules. Consider the nearby baz.py source file:

from foo import foo

def baz():
    return 2 * foo()

We wouldn't want that initial import line to be noisy, or have other side effects like changing a file or failing when a server's down. The if protection lets other modules reliably import, safe in the knowledge that only "boring" things like class and function definitions will be happening.

In a notebook, we seldom encounter such considerations. So a simple call to main1(), without an if, makes sense.

Related