1

I have a simple python project with the following directory structure:

sample-project/
main/
    config/
        config.yaml
    docker/
        Dockerfile
    tests/
        __init__.py
        sometests.py
    config.py
    run.py
    __init__.py
requirements.txt
README.rst

In the config.py file, I have:

import yaml


class Config:

def __init__(self):
    with open("config/config.yaml", 'r') as ymlfile:
        cfg = yaml.load(ymlfile)

        self.host = cfg["mysql"]["host"]
        self.database = cfg["mysql"]["database"]
        self.user = cfg["mysql"]["user"]
        self.password = cfg["mysql"]["password"]


my_config = Config()

In the run.py file, I have an import statement as follows:

from main.config import my_config

when I run using command line: python3.5 run.py, I get the error:

from main.config import my_config

ImportError: No module named 'main'

But when I add this in run.py imports it works:

import sys
sys.path.append('/home/tomas/sample-project/')

Is there any better way to make it work rather than give absolute path or any other way? Please give some example :)

1
  • 1
    You could append the part relative using sys.path.append('..'). Commented Jan 2, 2020 at 11:30

3 Answers 3

1

Generally, never ever touch sys.path from within your program.

Since main/ (not the best name) contains an __init__.py, we'll consider it a package, so let's make it runnable as one. This way imports will be considered correctly.

Add main/__main__.py with e.g.

from main.run import run

if __name__ == "__main__":
   run()

Then run your app with

python -m main

instead of

python main/main.py
Sign up to request clarification or add additional context in comments.

4 Comments

I don't think it works what you said or I'm doing something wrong...
/usr/bin/python3.5: No module named main
Are you running that from the directory where main/ is?
Yep, running from '/home/tomas/sample-project/' - next directory is main.. even cd into main and tried but same error.
0

when mentioning below from main.config import my_config

keep dir path also eg: from sample-project/main.config import my_config

assuming you are executing from /home/tomas

Comments

0

Although I share AKX's sentiment that editing your path is something to avoid I would generally suggest the following method:

import sys
from os.path import dirname
abs_dir = dirname(__file__)
sys.path.append(abs_dir)

The __file__ variable provides access to the location of the file in which it is accessed. This allows you to get an absolute path to any file in your project.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.