Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to import modules from parent sub-directory

Tags:

I want to import a class from a python file in a directory in the parent directory. This is my current folder structure:

│   run_simulation_from_parent.py
│   __init__.py
│
├───.vscode
│       launch.json
│       settings.json
│
├───mod
│   │   mods.py
│   │   __init__.py
│   │
│   └───__pycache__
│           __init__.cpython-37.pyc
│
├───sim
│   │   run_simulation.py
│   │   __init__.py
│   │
│   └───__pycache__
│           __init__.cpython-37.pyc
│
└───__pycache__
        __init__.cpython-37.pyc

The file mod/mods.py contains the following class:

class Objective:
    """Objective function class"""

    def __init__(self, x):
        self.x = x

The file sim/run_simulation.py contains:

from mod.mods import Objective

x = 5
obj = Objective(x)

When I try to run this I get the following error:

  File "sim/run_simulation.py", line 1, in <module>
    from mod.mods import Objective
ModuleNotFoundError: No module named 'mod'

In visual studio code it does autofill when I start typing mod.mods and import Objective

When I run run_simulation_from_parent.py with the following content I have no problems:

from mod.mods import Objective

x = 5
obj = Objective(x)

print(obj.x)

How can I do this from the directory sim? I already tried the following:

  1. Use from ..mod.mods import Objective to run_simulation.py
  2. Use init.py files with the following content: import os, sys sys.path.append(os.path.dirname(os.path.realpath(__file__)))

  3. Without the __init__.py files

Edit: I run the file from visual studio code where I start in the parent directory. I also tried from the command line in windows from the sim folder where I used

python run_simulation.py
like image 394
user3223765 Avatar asked Jun 28 '19 12:06

user3223765


People also ask

How do I import a module into a module?

The import statement You need to use the import keyword along with the desired module name. When interpreter comes across an import statement, it imports the module to your current program. You can use the functions inside a module by using a dot(.) operator along with the module name.

How do you use relative import in Python?

Relative imports use dot(.) notation to specify a location. A single dot specifies that the module is in the current directory, two dots indicate that the module is in its parent directory of the current location and three dots indicate that it is in the grandparent directory and so on.


1 Answers

The way I deal with imports inside a project is to install the project in editable mode. This way, all files will be able to locate each other, always starting from your project root directory.

In order to do this, follow these steps:

1) write a setup.py file and add it to your project root folder - it doesn't need much info at all:

# setup.py
from setuptools import setup, find_packages

setup(name='MyPackageName', version='1.0.0', packages=find_packages())

2) install your package in editable mode (ideally from a virtual environment). From a terminal in your project folder, write

$ pip install -e .

Note the dot - this means "install the package from the current directory in editable mode".

3) your files inside the project are now able to locate each other, always starting from the project root. To import Objective, for example, you write:

from mod.mods import Objective

This will be true to import Objective for any file, no matter where it is located in the project structure.

Like I said, you should use a virtual environment for this, so that pip does not install your package to your main Python installation (which could be messy if your project has many dependencies).

My favorite tool for this is pipenv. When using it, replace the terminal command with

$ pipenv install -e .

So that your project gets added to the Pipfile.

like image 163
jfaccioni Avatar answered Sep 21 '22 17:09

jfaccioni