childerico
childerico

Reputation: 89

Which is the correct way of handling imports in complex Python project?

I have always used Python for single-file scripts and now I am working on my first "complex" project, so I have not experience with packages in Python (3.x).

I know this is a frequently asked question, but I am missing something for successfully organizing module imports in my project, which should be used as a library.

Assuming following project tree:

myProject/
- subpackage1/
   - __init__.py
   - other1.py
- subpackage2/
   - __init__.py
   - other2.py
- __init__.py
- foo.py
- bar.py

Which is the correct way of importing modules from each other? In particular:

  1. importing foo from bar
  2. importing foo from other1
  3. importing other1 from other2
  4. importing foo (which is a library) from a different directory during development (are virtual environments the right choice?)

Thanks!

EDIT: (to make the question more specific) I obviously tried different approaches before asking. What I saw in some popular projects is using absolute imports like from myProject.subpackage1.other1 import something. It looks like a clean solution (similar to what I'm used to do in Java), but when adopting this approach I can't simply run my code due to import errors. Could virtualenv be a solution to install the packages before trying to import them?

Upvotes: 4

Views: 679

Answers (1)

1. Importing foo from bar

As the tutorial says, you can import modules from the same directory by importing from .. For example:

from . import foo

If bar is executed with python bar.py then you could also import it absolutely, like any other module:

import foo

This works since the parent directory of the executed file is added to the module search path (sys.path/PYTHONPATH). However, I wouldn't rely on that behaviour since it means different things for imported modules and the main module.

2. Importing foo from other1

If you're using the relative import syntax then you can add another . to mean the parent directory:

from .. import foo

3. Importing other1 from other2

This shouldn't be much of a surprise by now, but you can use relative imports with modules in subpackages, too:

from ..subpackage1 import other1

4. Importing foo (a library) from a different directory during development

I'm assuming that by "a different directory" you mean "a different project". In that case, yes, you'd want to package foo as a distutils/setuptools package, and then install that into a virtualenv for the other project.

Exactly how to do that is a bit more involved for a post that's already getting pretty long, but the setuptools website has a pretty decent tutorial for doing this.

Upvotes: 2

Related Questions