4

I am working in Jupyter notebook. I created a simple module called conv.py for converting miles to km. When I try to import this module in a separate code (in the same directory) the import seems to go successfully but it doesn't recognize either of the functions I defined in the 'conv' module.

I have imported os and os.getcwd() provides the correct folder for conv.py...

code for conv.py

 in_n_ft = 12
 ft_n_mile = 5280
 m_n_km = 1000
 cm_n_in = 2.54
 cm_n_m = 100
 mm_n_m = 1000
 def ft_to_km(feet):
     return feet*in_n_ft*cm_n_in/cm_n_m/m_n_km
 print(ft_to_km(5280))
 def mil_to_km(mile):
     return mile*ft_n_mile*in_n_ft*cm_n_in/cm_n_m/m_n_km
    
 print(mil_to_km(3.2)) 

Code for new module

 import conv
 km = conv.mil_to_km(5) 

Error provided


AttributeError                            Traceback (most recent call last)
<ipython-input-111-bfd778724ae2> in <module>
      3 import conv
      4 
----> 5 km = conv.mil_to_km(5)
AttributeError: module 'conv' has no attribute 'mil_to_km'

When I type

dir(conv)

I get

['__builtins__',
 '__cached__',
 '__doc__',
 '__file__',
 '__loader__',
 '__name__',
 '__package__',
 '__spec__']

What am I doing wrong?

EDIT

I have also tried

from conv import mil_to_km

when I do that I get a different error

cannot import name 'mil_to_km' from 'conv' (C:\Users\223023441\Documents\python\conv.py)

I have also queried the module using:

from inspect import getmembers, isfunction
import conv

print(getmembers(conv, isfunction))

from here I get:

['__builtins__',
 '__cached__',
 '__doc__',
 '__file__',
 '__loader__',
 '__name__',
 '__package__',
 '__spec__']

I am also unable to access any of the variables within the conv.py file after import... Am I doing something wrong when I save the py file? Jupyter makes ipynb as the common file, when I 'save as' to conv.py, is this screwing it up?

ningineering
  • 61
  • 1
  • 5
  • 1
    Does `conv.__file__` match the name the file you think you are importing? – chepner Aug 12 '21 at 15:21
  • Or did you edit the file without reloading it into the same iPython session? Simply "re"importing it won't work, because it will see that the module `conv` already exists and not re-import the file. – chepner Aug 12 '21 at 15:24
  • Even if you import your new module, if an old version of `conv` is already defined, the new module won't import the new version. – chepner Aug 12 '21 at 15:27
  • @chepner yes the name does match. I just exited my python session and reloaded jupyter notebook from the CMD window (is this what you mean). Still having the same error – ningineering Aug 12 '21 at 15:33
  • If you aren't seeing the output of the two `print` statements in `conv.py`, then you aren't importing that module. – chepner Aug 12 '21 at 15:35
  • @chepner I did log out of jupyter and closed it in my browser. Opened again from CMD and tried running my main file. No success – ningineering Aug 12 '21 at 15:37
  • Please provide the exact paths of *all* the files you are importing or executing, along with the output of `conv.__file__` after the import. – chepner Aug 12 '21 at 15:42
  • @chepner So it looks like I am not importing the module then... – ningineering Aug 12 '21 at 15:42
  • @chepner C:\Users\XXXXXXXXX\Documents\python\ is the folder that both files are stored in C:\Users\XXXXXXXXX\Documents\python\conv.py is output of conv.__file__ – ningineering Aug 12 '21 at 15:45
  • How about `conv.__spec__`? (I'm grasping at straws, here; this isn't making any sense. *Something* is getting imported, or `import conv` would raise an error. But it's clearly not importing the `conv.py` shown, and I'm not sure what the other possibilities are.) – chepner Aug 12 '21 at 15:54
  • ModuleSpec(name='conv', loader=<_frozen_importlib_external.SourceFileLoader object at 0x00000289CA47F6A0>, origin='C:\\Users\\223023441\\Documents\\python\\conv.py') Am I saving the conv file correctly? notebook creates a .ipynb file for editing and I "saveas" and type conv.py on my own... Is this a problem? – ningineering Aug 12 '21 at 16:06
  • It's not providing an error on the import but it doesn't seem to be importing anything. The variables should be defined as soon as I import it too correct? After importing, I can't access the variables either. So is something happening when I am saving the conv.py file? – ningineering Aug 12 '21 at 16:20
  • 1
    And the origin is the same value as `conv.__file__`? I'm out of ideas here. – chepner Aug 12 '21 at 16:33
  • @chepner Thanks for trying. Something is telling me it is an issue with the way I am saving it... – ningineering Aug 12 '21 at 16:34
  • @chepner it was def the way that I was saving the .py file in jupyter. See my answer on this page – ningineering Aug 12 '21 at 16:51

2 Answers2

1

So the ultimate issue was the way I was saving the .py file... I was using the 'save as' command in jupyter notebook and typing 'conv.py' for my file save... This was showing up in the directory as a .py file, but my main file wasn't recognizing it properly. Once I downloaded the file as a .py file, cut from my downloads folder and pasted into my working directory everything worked...

ningineering
  • 61
  • 1
  • 5
0

You should import from the module. Try this:

from conv import mil_to_km

km = mil_to_km(5) 

The reason is that when you import the module in that way, you are executing it. In the way I shown, you are just importing the needed functions.

Sprizgola
  • 416
  • 2
  • 10
  • When I do that I get: ImportError: cannot import name 'mil_to_km' from 'conv' (C:\Users\223023441\Documents\python\conv.py) – ningineering Aug 12 '21 at 15:05
  • Sorry, i edit the answer; i mistakenly pasted conv.mil_to_km(5) without removing conv. Try now – Sprizgola Aug 12 '21 at 15:08
  • It fails before getting to that point. The error comes when trying to import mil_to_km from conv – ningineering Aug 12 '21 at 15:19
  • are conv and main in the same directory? – Sprizgola Aug 12 '21 at 15:20
  • 2
    The only difference between this and `import conv` is that the only name bound in the global scope is `mil_to_km`, and it's bound to the function in the module. The file itself is still (necessarily) executed to define the module, and the module in its entirety is still accessible from `sys.modules['conv']`. – chepner Aug 12 '21 at 15:22
  • Also, wouldn't I need to import the whole module as it contains the conversion factors that are used in mil_to_km? – ningineering Aug 12 '21 at 15:26
  • They are in the same directory – ningineering Aug 12 '21 at 15:27
  • 1
    As @chepner said, the file is still executed after you import it, so the conversion factors are declared the time when you import the conv module. – Sprizgola Aug 12 '21 at 15:28