Home > Back-end >  NameError when trying to import function from another script
NameError when trying to import function from another script

Time:06-10

I've seen many posts on this and the solution always seems to be to add * when importing the original script to be able to access its functions. I have done this and still get the error.

I have a file called toolbox.py whose path is: /Users/justinbenfit/Desktop/Programming/Python/Explorium /transformations_deduping/ipynb/toolbox.py and contains the following:

def tz():
    print('works')

Then I have a file called explorium_check_acceptable.ipynb whose path is: /Users/justinbenfit/Desktop/Programming/Python/Explorium /transformations_deduping/ipynb/explorium_check_acceptable.ipynb

and contains:

from toolbox import *
tz()

which results in:

NameError                                 Traceback (most recent call last)
/var/folders/cf/ft88j_856fv5rk3whgs12d9w0000gq/T/ipykernel_20696/4114475549.py in <module>
      2 import numpy as np
      3 from toolbox import *
----> 4 tz()

NameError: name 'tz' is not defined

I don't know what else could be wrong unless you can't import functions from a .py file to a .ipynb file.

update: I ran

!export PYTHONPATH=.
!python -m site

in one of my ipynb code blocks and got this:

sys.path = [
    '/Users/justinbenfit/Desktop/Programming/Python/Explorium /transformations_deduping/ipynb',
    '/Users/justinbenfit/opt/anaconda3/lib/python39.zip',
    '/Users/justinbenfit/opt/anaconda3/lib/python3.9',
    '/Users/justinbenfit/opt/anaconda3/lib/python3.9/lib-dynload',
    '/Users/justinbenfit/opt/anaconda3/lib/python3.9/site-packages',
    '/Users/justinbenfit/opt/anaconda3/lib/python3.9/site-packages/aeosa',
    '/Users/justinbenfit/opt/anaconda3/lib/python3.9/site-packages/locket-0.2.1-py3.9.egg',
]
USER_BASE: '/Users/justinbenfit/.local' (exists)
USER_SITE: '/Users/justinbenfit/.local/lib/python3.9/site-packages' (exists)
ENABLE_USER_SITE: False

CodePudding user response:

To debug import issues, it is always helpful to view (and post on SO) the output of python -m site, which will reveal the contents of sys.path in a readable way.

You will usually want

export PYTHONPATH=.

or similar, to ensure that current directory is in sys.path.

Notice that you'll need that export in the context of the running python kernel, when you start it. Also, the current working directory at time of starting will make a difference. Inspect sys.path within your notebook to verify, perhaps using:

from pprint import pp
import sys

pp(sys.path)

It appears you have this module in your path: https://pypi.org/project/toolbox

Try

from toolbox import Item

to verify that.

Also, as a very generic way of testing such import details, a rename to e.g. toolbox1.py is a good sanity check. That is, we expect the import's success to track whether it has caught up with the new name yet, or not.

A classic example is some poor student naming a file test.py. Notice that python -c 'import test' always succeeds, since there is a seldom-used builtin test module.


Prefer

from toolbox import tz

over the * format. It makes your code easier to read and to analyze. And here, it would offer a clearer diagnostic, failing in the import statement rather than waiting until the tz() reference.

  • Related