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:
from ..mod.mods import Objective
to run_simulation.pyUse init.py files with the following content: import os, sys sys.path.append(os.path.dirname(os.path.realpath(__file__)))
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
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With