pythonipythonjupyter-notebookipython-magic

IPython %run magic -n switch not working


I'm running an IPython notebook by using the %run magic in another (parent) notebook.

I would like to hide some of the output in the child notebook if it is called using %run and think I can do this by testing for if __name__ == '__main__'

The IPython documentation says that, when %run -n switch is used:

__name__ is NOT set to __main__, but to the running file's name without extension (as python does under import). This allows running scripts and reloading the definitions in them without calling code protected by an if __name__ == "__main__" clause.

However, it does not seem to be workign for me. I tried this:

In sub_notebook.ipynb:

print(__name__)

In parent_notebook.ipynb:

%run -n sub_notebook.ipynb

This prints __main__ but the documentation says that it should have printed sub_notebook.

Please could you let me know how I can selectively run code in sub_notebook.ipynb depending on whether it is being run alone or using %run?

I'm running IPython version 6.1.0


Solution

  • The source code to %run sets the __file__ variable so we can test for this.

    We can write in sub_notebook.ipynb:

    try:
        __file__
        print('I am in an imported notebook')
    
    except NameError:
        print('I am not in an imported notebook')
    

    Run alone, this prints I am not in an imported notebook

    The we can create a parent notebook parent_notebook.ipynb containing:

    %run sub_notebook.ipynb
    

    Running this correctly prints I am in an imported notebook.

    We can write a simple test within sub_notebook.ipynb:

    def has_parent():
        """Return True if this notebook is being run by calling
        %run in another notebook, False otherwise."""
        try:
            __file__
            # __file__ has been defined, so this notebook is 
            # being run in a parent notebook
            return True
    
        except NameError:
            # __file__ has not been defined, so this notebook is 
            # not being run in a parent notebook
            return False
    

    Then code which should not print in the parent notebook can be protected:

    if not has_parent():
        print('This will not print in the parent notebook')