Sunday, 6 September 2020

How to properly structure internal scripts in a Python project?

Consider the following Python project skeleton:

proj/
├── foo
│   └── __init__.py
├── README.md
└── scripts
    └── run.py

In this case foo holds the main project files, for example

# foo/__init__.py
class Foo():
    def run(self):
        print('Running...')

And scripts holds auxiliary scripts that need to import files from foo, which are then invoked via:

[~/proj]$ python scripts/run.py

There are two ways of importing Foo which both fail:

  1. If a relative import is attempted from ..foo import Foo then the error is ValueError: attempted relative import beyond top-level package
  2. If an absolute import is attempted from foo import Foo then the error is ModuleNotFoundError: No module named 'foo'

My current workaround is to append the running path to sys.path:

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

from foo import Foo
Foo().run()

But this feels like a hack, and has to be added to every new script in scripts/.

Is there a better way to structure scripts in such projects?



from How to properly structure internal scripts in a Python project?

No comments:

Post a Comment