How to run an existing function from Jupyter notebook - python

I am using Jupyter notebook. In the same folder in which the notebook is running, I have a function f defined as
def f(x):
return x**2
I have saved this function as f.py in the same folder. Now I want to call this function in the notebook that is running. How do I do that? If the function was typed into the notebook, I could have just typed
f(4)

Try the load magic;
%load f.py
That automatically loads the in the entire contents of file so that you can edit it in a cell.
from f import f
Is another option.
If neither one of those work for you could try adding your notebook's directory to the the system path by running this block as a cell before trying to call your function;
import os
import sys
nb_dir = os.path.split(os.getcwd())[0]
if nb_dir not in sys.path:
sys.path.append(nb_dir)

%run f.py
load magic was just copying the whole file into a cell, which was not what i need. Neither did the importing worked for me. was throwing some weird errors. So i ended up using the run magic.

Related

ImportError: cannot import name 'MyClass' from "myFile.py", without restarting the notebook

Using VSCode, I have a file myFile.py with a class myClass
# myFile.py
class myClass(nn.Module):
def __init__(self):
super(myClass, self).__init__())
self.a = 1
No in a JupyterNotebook someNb.ipynb inside the same folder as myFile.py I just want to import myClass in a python cell:
from myFile import myClass
However, even though I am saving both files (as stated in other questions), I get the following error:
ImportError: cannot import name 'myClass' from 'myFile' (<path-to-myFile.py>)
I also tried to add
%load_ext autoreload
%autoreload 24
before from myFile import myClass, but also this does not see the changes in myFile.py.
Note: When I reopen the notebook it works. And <path-to-myFile.py> is the correct path.
So the issue is more: Why do I need to reopen the whole notebook everytime I am making changes to myFile.py? I just want to make changes to myFile.py, save both someNb.ipynb and myFile.py, and import the new changes (classes), without reloading the notebook and loosing all variables.
According to the explanation here, this is the mechanism of jupyter.
If it is modified in an external file (such as a python file), the change will not be recognized in jupyter. Because this module is already imported after opening jupyter for the first time and running the code, the interpreter kernel already exists this module.
So if you want the jupyter kernel to notice the change, you have to restart jupyter.

Import on shared object fails with ModuleNotFound only when script is executed from command line

ran into a weird problem where there is a shared-object import error only when I run the script from command line. It succeed if i run the script in the python console using exec(...)
I have a class that needs a shared object: foo.py:
import os
cur_dir = os.curdir()
os.chdir('/tmp/dir_with_shared_object/')
import shared_object_class
os.chdir(cur_dir)
class Useful:
... # use the shared object import
Then there is a script like this:
from foo import Useful
If I enter python console and run:
exec(open('script.py').read())
Everything works fine.
If I run this on command line:
python script.py
I will get
ModuleNotFoundError: No module named 'shared_object_class'
The python is the same. It is 3.7.3, GCC 7.3.0 Anaconda. Anyone knows what is causing this discrepancy in behavior for shared object import?
A standard way of importing from a custom directory would be to include it in the PYTHONPATH environmental variable, with export PYTHONPATH=/tmp/dir_with_shared_object/.
update
It could also be done dynamically with
import sys
p = '/tmp/dir_with_shared_object/'
sys.path.insert(0, p)
PS
I think I have an explanation for why OP's original code didn't work. According to this python reference page, the import system searches, inter alia, in "[t]he directory containing the input script (or the current directory when no file is specified)." So the behavior in the REPL loop is different from how it is when running a script. Apparently the current directory is evaluated each time an import statement is encountered, while the directory containing the input script doesn't change.

ImportError Only in Jupyter Notebook

When I try importing functions and classes that I've created in Python scripts into a Jupyter Notebook, I get import errors. However, when I run the same code in a regular script rather than in a notebook, it runs without a problem.
All three files are in the same directory:
First, I have my_function_script.py, which defines functions.
def my_function():
pass
Second, I have my_class_script, which both imports the functions defines classes:
from my_function_script import my_function
class my_class():
pass
When I try to run the below import script in a Jupyter Notebook, I get an ImportError.
from my_class_script import my_class
ImportError Traceback (most recent call last)
<ipython-input-6-8f2c4c886b44> in <module>
----> 1 from my_class_script import my_class
~\my_directory\my_class_script.py in <module>
5
----> 6 from my_function_script import my_function
ImportError: cannot import name 'my_function' from 'my_function_script' (C:\Users\my_directory\my_function_script.py)
I believe that the problem is specific to the Jupyter Notebook for two reasons. First, I've confirmed that both my_function_script.py and my_class_script.py can run in the terminal without error. Second, when I take the same line that causes the Jupyter Notebook to error and run it in a regular Python script, it runs without error.
I have Windows, and I don't have multiple environments or versions of Python.
you can add to the Python path at runtime:
# some_file.py
import sys
# insert at 1, 0 is the script path (or '' in REPL)
sys.path.insert(1, '/path/to/application/app/folder')
import file
this usually happens when your jupyter notebook does not point to the correct directory for importing
one way to fix this would be to change the working directory in jupyter notebook
import os
os.chdir('path/to/python/scripts/directory')
from my_class_script import my_class
another way to do this is using UNIX commands directly in jupyter notebook
cd /path/to/python_script_directory
from my_class_script import my_class
make sure you dont put the cd command and import statement in the same notebook block

Jupyter Lab/Notebook magic command %load with platform independent path

I am trying to develop a Jupyter notebook that includes cells that have the %load magic command to load code from elsewhere. This code is not in the same directory as where the notebook is. I want this to work on Windows, Linux and Mac, so path separators should sometimes be '\' and sometimes '/'.
Usually I would solve this by using os.path.join. Nevertheless, when I do this in a line with the load command, the notebook just evaluates the path, and doesn't actually load the code. Is there a way of doing this, other than first just changing the working directory and changing it back after executing the code that I loaded?
Brief example:
import os
%load os.path.join('example', 'file.py')
This gives an error as it will actually search for a file with the name os.path.join('example', 'file.py'). If I first evaluate that and put the result in load I get:
import os
to_include = os.path.join('example', 'file.py')
print(to_include)
%load to_include
That evaluates to just
# %load to_include
example/file.py
But obviously I want the content of that file loaded, not the path + filename. What am I doing wrong?
In Jupyter you have to expand variables in a bash-like syntax for them to work in magic functions.
That's why you will have to use the $ sign.
In your case:
import os
to_include = os.path.join('example', 'file.py')
%load $to_include

importing functions from another jupyter notebook

I am trying to import a function from another jupyter notebook
In n1.ipynb:
def test_func(x):
return x + 1
-> run this
In n2.ipynb:
%%capture
%%run n1.ipynb
test_func(2)
Error:
NameError Traceback (most recent call last)<ipython-input-2-4255cde9aae3> in <module>()
----> 1 test_func(1)
NameError: name 'test_func' is not defined
Any easy ways to do this please?
The nbimporter module helps us here:
pip install nbimporter
For example, with two notebooks in this directory structure:
/src/configuration_nb.ipynb
analysis.ipynb
/src/configuration_nb.ipynb:
class Configuration_nb():
def __init__(self):
print('hello from configuration notebook')
analysis.ipynb:
import nbimporter
from src import configuration_nb
new = configuration_nb.Configuration_nb()
output:
Importing Jupyter notebook from ......\src\configuration_nb.ipynb
hello from configuration notebook
We can also import and use modules from python files.
/src/configuration.py
class Configuration():
def __init__(self):
print('hello from configuration.py')
analysis.ipynb:
import nbimporter
from src import configuration
new = configuration.Configuration()
output:
hello from configuration.py
Something I've done to import functions into a Jupyter notebook has been to write the functions in a separate Python .py file then use the magic command %run in the notebook. Here's an example of at least one way to do this:
Both notebook.ipynb and helper_functions.py are in the same directory.
helper_functions.py:
def hello_world():
print('Hello world!')
notebook.ipynb:
%run -i helper_functions.py
hello_world()
notebook.ipynb output:
Hello world!
The %run command tells the notebook to run the specified file and the -i option runs that file in the IPython namespace, which is not really meaningful in this simple example but is useful if your functions interact with variables in the notebook. Check out the docs if I'm not providing enough detail for you.
For what it's worth, I also tried to run function definitions in an outside .ipynb file rather than a outside .py file and it worked for me. Might be worth exploring if you want to keep everything in notebooks.
Based on answer of Kurt:
%run -i configuration.ipynb
This runs another notebook and in the next cell you are able to access the variables defined by that notebook.
This works for me
from some_dir.pythonFile import functionName
%run ./some_dir/pythonFile.py
This works as well:
%load_ext autoreload
%autoreload 2
from some_dir.pythonFile import functionName

Categories