ImportError Only in Jupyter Notebook - python

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

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.

Python Code Runs in Spyder but not Anaconda Prompt -- ModueNotFoundError

I am in need of some help with the below. Using Python 3 code on Windows 10. Written in Spyder over Anaconda install and custom environment.
I have some code that runs in Spyder but not Anaconda Prompt. It gets a ModuleNotFoundError. The directory/file structure is like this:
my_python
smb_bau
etl
init.py
etl_globals.py
init.py
my_config.conf
my_connections.py
my_definitions.py
init.py
(underscores round init not displaying for some reason)
Some notes before the problematic code:
It's just test code for now that will be replaced with the real hive code later.
The code works when all the files are in one foler.
Th my_ prefixes are just to avoid any word that might cause issues while testing.
In my_connections I have this code:
class hive_connection:
def __init__(self):
self.my_name = None
self.my_town = None
import configparser
from smb_bau.my_definitions import CONFIG_PATH
config = configparser.ConfigParser()
config.read(CONFIG_PATH)
my_details = config["my_details"]
self.my_name = my_details["my_name"]
self.my_town = my_details["my_town"]
And this is what's in my_definitions:
import os
ROOT_DIR = os.path.dirname(os.path.abspath(__file__))
CONFIG_PATH = os.path.join(ROOT_DIR, 'my_config.conf')
(I gratefully stole this from another thread to solve the issue of getting config info from a different folder).
The file I run is etl_globals which contains this code:
from smb_bau.my_connections import hive_connection
hive = hive_connection()
print(hive.my_name, hive.my_town)
When I run etl_globals in Spyder it works perfectly. But it fails in Anaconda Prompt.
I open up Anaconda Prompt, activate my environment, navigate to the etl folder, and enter python etl_globals.py
The error message I get is:
Traceback (most recent call last):
File "etl_globals.py", line 1, in
from smb_bau.my_connections import hive_connection
ModuleNotFoundError: No module named 'smb_bau'
I don't understand why the import of modules works in Spyder but not Anaconda Prompt.
The overarching goal is to be able to not have all the files in one folder.
Any help would be gratefully appreciated.
Many thanks.
Edit:
Just to be sure what the issue is I simplified it to create a file called my_functions (in the smb_bau folder) with this in:
def fn_test():
print(5)
And a file in the etl folder called my_test with this in:
from smb_bau.my_functions import fn_test
fn_test()
And got the same error:
Traceback (most recent call last):
File "my_test.py", line 1, in
from smb_bau.my_functions import fn_test
ModuleNotFoundError: No module named 'smb_bau'
Why does from smb_bau.my_functions import xxx work in Spyder but not Anaconda prompt?
Also, this may be relevant: the only reason there is a folder called my_python at the top is that I was getting an error saying no module named smb_bau. So I moved it all down a level and then it would accept smb_bau as a module but only in Spyder).
I also just checked PYTHONPATH and the root folder is there.
I have only been using Python for a week so I'm sure there are other bit of my code that aren't great -- but it does work in the spyder client.
Thanks and sorry if any of this is unclear.

Python script correctly executes every statement, but also returns ModuleNotFoundError

I'm running my Python script in Terminal on MacOS.
The script1.py source code:
# A first Python script
import sys # Load a library module
print(sys.platform)
print(2 ** 100) # Raise 2 to a power
x = 'Spam!'
print(x * 8) # String repetition
The output in the Python interactive session:
>>> import script1.py
darwin
1267650600228229401496703205376
Spam!Spam!Spam!Spam!Spam!Spam!Spam!Spam!
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'script1.py'; 'script1' is not a package
All the statements in the script are executed correctly, but the interpreter returns an error that says the script can't be found.
What's going on here?
import script1.py
The interpreter is thinking you're trying to import the module named py from inside the package script1.
Now, it can find a file called script1 - that's your file called script1.py. So it goes ahead and loads it. And "loading" for python means running the statements inside the file. So it does that. And you get your output.
Then the interpreter realizes that it was expecting py to be a module, so script1 should've been a package (i.e. a directory with source files inside it). But script1 was just an ordinary file. Hence it throws that error.
When trying to import a module named script1.py, you should use:
import script1
When trying to run a file called script1.py, you may use:
python script.py
You should delete the .py at the end. When you import sys you also dont write import sys.py. See also this post answering how to import your own scripts in python.

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

How to run an existing function from Jupyter notebook

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.

Categories