Megdatronica
Megdatronica

Reputation: 75

Importing between nested packages in Python 3

Running Python 3.6.1, and I'm trying to get a file (world.py) to import from another package in my project.

My directory structure:

+-- test_project
|   +-- sub_project1
|   |   +-- __init__.py
|   |   +-- hello.py
|   +-- sub_project2
|   |   +-- __init__.py
|   |   +-- world.py

hello.py:

def say_hello():
    return("Hello ")

world.py:

from test_project.sub_project1.hello import say_hello

print(say_hello() + "world!")

When I go into the sub_project2 directory and run world.py, I keep getting this:

ModuleNotFoundError: No module named 'test_project'

I've tried rewriting the import statement to from sub_project1.hello import say_hello. I've also tried having the test_project directory in my PATH environment variable. I've tried having the test_project's parent directory in my PATH. I've tried having the sub_project2's directory in my PATH. I've searched for answers online and can't work out what I'm missing.

What am I doing wrong here?

Upvotes: 2

Views: 398

Answers (2)

Ezequiel Salas
Ezequiel Salas

Reputation: 59

The problem is that you have to add your project to python path. The reason is that python first search in these locations:

  1. the directory containing the input script (or the current directory).

  2. PYTHONPATH (a list of directory names, with the same syntax as the shell variable PATH).

  3. the installation-dependent default.

So, you have to add to PYTHONPATH environment variable the directory C:\Users\your_user\dir_before_test_project\

Upvotes: 1

Alperen
Alperen

Reputation: 4652

You need to add the path of "hello.py" to sys.path

import sys
sys.path.append('../sub_project1')

from hello import say_hello

print(say_hello() + "world!")

Output:

Hello world!

Source is here. This discussion is really helpful.

EDIT: Because "sub_project1" has __init__.py, you can use:

import sys
sys.path.append('..') #Adds upper directory sys.path

from sub_project1.hello import say_hello

print(say_hello() + "world!")

Upvotes: 2

Related Questions