Relative import in Python 3 is not working [duplicate]

Launching modules inside a package as executables is a bad practice.

When you develop something you either build a library, which is intended to be imported by other programs and thus it doesn’t make much sense to allow executing its submodules directly, or you build an executable in which case there’s no reason to make it part of a package.

This is why in you distinguish between packages and scripts. The packages will go under site-packages while the scripts will be installed under /usr/bin (or similar location depending on the OS).

My recommendation is thus to use the following layout:

├── mydirectory
|    ├──
|    ├── 

Where imports as any other code that wants to use the library mydirectory, with an absolute import:

from mydirectory.file1 import f

When you write a script for the project you simply list mydirectory as a package and as a script and everything will work. No need to fiddle with sys.path.

If you ever, for some reason, really want to actually run a submodule of a package, the proper way to do it is to use the -m switch:

python -m mydirectory.file1

This loads the whole package and then executes the module as a script, allowing the relative import to succeed.

I’d personally avoid doing this. Also because a lot of people don’t even know you can do this and will end up getting the same error as you and think that the package is broken.

Regarding the currently accepted answer, which says that you should just use an implicit relative import from file1 import f because it will work since they are in the same directory:

This is wrong!

  • It will not work in python3 where implicit relative imports are disallowed and will surely break if you happen to have installed a file1 module (since it will be imported instead of your module!).
  • Even if it works the file1 will not be seen as part of the mydirectory package. This can matter.

    For example if file1 uses pickle, the name of the package is important for proper loading/unloading of data.

Leave a Comment