ModuleNot FoundError : No module named 'lib'
Asked Answered
D

3

8

I am trying to understand import mechanism behind python but this piece of code gives error.

Here is my folder structure:

import_test
  -calculator
   ..__init__.py
   ..operation.py
  -lib
   ..__init__.py
   ..multiply.py

It is working when i ran on PyCharm IDE, but if i run from command line like

'py operation.py'(for now windows,for the next phase i will try on raspbian RPi)

i am getting module not found error! Tried many ways from forums on internet but still no progress.

multiply.py:

def multiplier(a,b):
    return a + b

operation.py:

from lib.multiply import multiplier
print (multiplier(3,4))

lib/init.py:

from .multiply import multiplier

This is the output of my running:

File "operation.py", line 1, in <module>
    from lib.multiply import multiplier
ModuleNotFoundError: No module named 'lib'
David answered 2/8, 2019 at 14:9 Comment(6)
Try having __init__.py in the root directory(import_test) as wellHalley
with empty content? @SundeepPiduguDavid
@mert yes, empty is fine. Python checks for the existence of __init__.py (irrespective of whether it has any contents) to determine whether or not something counts as a module.Nusku
Ok. Created empty init.py but no change @GreenCloakGuyDavid
Try to run like this python -vv operation.py python will print lots of info include all possible places where it's looking for the modules.Copter
This is just one of the reasons why python is a joke of a language. These imports.Bernie
D
1

To go up a directory, to another directory, and back down, almost always requires editing the sys.path pycharm tends to do this automatically for a project, without really telling you it did.

using the structure you have in the question this should work:

import_test
  -calculator
   ..__init__.py (EMPTY FILE)
   ..operation.py
  -lib
   ..__init__.py (EMPTY FILE)
   ..multiply.py

operation.py:

import os
import sys

# insert the "import_test" directory into the sys.path
sys.path.insert(1, os.path.abspath(".."))

from lib.multiply import multiplier

print (multiplier(3,4))

multiply.py:

def multiplier(a,b):
    return a + b

Running operation.py returns:

7

Dangelo answered 2/8, 2019 at 15:53 Comment(3)
Thanks for that useful answer but here is a more efficient way that i found: import sys sys.path.append("..") That's all! :)David
@mert The only reason I used os.path.abspath("..") is I've seen relative paths not work correctly in linux a few times, yet forcing the relative path to the absolute path worked. But if the straight relative path is working than great!Dangelo
@mert Also the sys.path.insert(1, path), is a preference for me, simply because it ensures that any additional items in the path are seen after the path I really want it paying attention too. This way any modules that have the same name will be superseded by the module I told it to look at.Dangelo
C
0

This is because when you are starting up your script from calculator directory, so python add's import_test/calculator to the sys.path, but it doesn't know anything about the lib.

You can either follow @tgikal advice and add parent directory to the sys.path but it looks like an ugly hack. Better way to handle this is to run your script like this

python -m calculator.operation, you might need to add an empty __init__.py file to the import_test directory, depends on your version of python.

Copter answered 3/8, 2019 at 4:9 Comment(0)
D
0

In my case, I had copied some code from another project that had user built modules in the imports at the top of the code, but I did not copy this user built module to my new project. I found this needed lib module folder in the original project and copied it to get rid of the message.

Diphyllous answered 3/3, 2022 at 10:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.