1

I have a file structure like this:

- __init__.py
- module.py
+ subpackage
|--- __init__.py
|--- submodule1.py
|--- submodule2.py
|--- etc
  • submodule1.py imports from submodule2.py
  • module imports from submodule1.py

To do this, I'm using relative imports. For example, in submodule1.py:

from .submodule2 import MyClass

The problem I'm running into is that now, using relative imports, I can't run submodule1.py as main. If I try, I get this error:

    from .module2 import MyClass
    ModuleNotFoundError: No module named '__main__.module2'; '__main__' is not a package

I like to include an if __name__ == "__main__": at the end of my modules for testing during development (and in some contexts a module might even be useful as a standalone script).

Is there a way to "have my cake and eat it too" on this one? Or is my best bet to migrate the code from if __name__ == "__main__": to a separate script?

Kieran
  • 25
  • 3

1 Answers1

2

It seems that you are attempting to run your modules as though they were independent scripts, rather than as member of a package. When you a run a module within a package, you need to let Python know where the module lies within your package structure. This is accomplished by invoking the Python interpreter using the -m command line flag. For instance, instead of writing

python3 ./my_package/subpackage/submodule1.py

run

python3 -m my_package.subpackage.submodule1

This will enable the interpreter to appropriately determine the structure of your package and to resolve any relative imports that you my use. See this related question about the use of the -m flag for more information.

Brian61354270
  • 8,690
  • 4
  • 21
  • 43
  • Thanks for the detailed answer! That makes a lot of sense. I had been looking for a way to preserve the functionality of the module as a script independent of the package structure, but honestly you've made me realize that's not very valuable. It's not hard to just change the imports if anyone ever wanted to rip the module out of the package. – Kieran Mar 10 '20 at 01:14