简体   繁体   中英

Is there a better way to set sys.path.append in python project?

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 :)

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 eg

from main.run import run

if __name__ == "__main__":
   run()

Then run your app with

python -m main

instead of

python main/main.py

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM