2

I tried reading other similar questions but the answers didn't work for me, like Python submodule imports using __init__.py and module has no attribute

I have a folder structure like so:

python_scripts
├── lib
│ ├── __init__.py # import lib.talk
│ └── talk.py # def sayhello(x): print(x)
│ 
├── src
│ ├── __init__.py # import lib.talk
│ └── data
│ ├── __init__.py # import lib.talk
│ └── main.py # from lib.talk import sayhello
│ sayhello('hi')
│
└── __init__.py # import lib.talk

This throws an error:

Traceback (most recent call last):
 File "main.py", line 1, in <module>
 from lib.talk import sayhello
ModuleNotFoundError: No module named 'lib.talk'

The strange thing is if I simply 'import lib' in main.py there is no error. How should I solve this?

I am using Windows and I would highly prefer to avoid using the sys.path method because we don't want to hardcode the path in (this may be used by other teams in the future).

asked Apr 10, 2018 at 11:23

2 Answers 2

4

In your main.py file, add following on the top.

import sys
path = r'{path_to_python_scripts}'
if path not in sys.path:
 sys.path.append(path)
# Now import
import lib

or

import sys, os
path = os.path.abspath('../..')
if path not in sys.path:
 sys.path.append(path)
# Now import
import lib

or How to import a module given the full path?

answered Apr 10, 2018 at 11:31
Sign up to request clarification or add additional context in comments.

1 Comment

Hi sorry I misunderstood - the second one works! Thank you.
0

Use from ...lib import talk. Your import lib.talk doesn't work since lib is a package because of __init__.py inside lib dictionary. You can also use path appending way, but you need to get it something like this:

import os, sys
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..', 'libs')))

This way you will always append path to libs dynamically no matter where your Python code is stored.

answered Apr 10, 2018 at 12:37

4 Comments

Hi, thanks for your reply. I tried both methods unfortunately it still throws an error: ImportError: cannot import name 'talk'
My bad. I didn't take a proper look at your directory tree. I have modified my answer. My small suggestion for you: when you build something like this main.py should be in the main directory, so all imports from subdirectory/subpackage will be relative to this script. At your solution, you need to go up over your directory tree and also other people will have a problem to find main.py.
thanks for your suggestion. i wanted this main.py to be the script to pull all the data (hence inside the data folder). there would be another app.py at the main directory for the actual app. maybe i should move main.py to the main directory and rename it pull_data.py
Separate data file and logic. data folder should be only for storing data. No Python files inside. Data parser should be inside lib and main.py should in the main directory. This way when you import parser from lib directory into main, path to data directory still be relative to main.py. It's easier to maintain.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.