I know there are A LOT of similar or the same questions, but i still cannot understand / find the right way for me to work with modules. Python is my favorite language, and i like everything in it except working with imports: recursive imports (when you try to reference a name that is not yet there), import paths, etc.
So, I have this kind of a project structure:
from package1 import module2
from . import module2
from package1 import module2
import os, sys
currDir = os.path.dirname(os.path.realpath(__file__))
rootDir = os.path.abspath(os.path.join(currDir, '..'))
if rootDir not in sys.path: # add parent dir to paths
This PEP is to change theidiom to
if __name__ == "__main__": ...
so that you at least have a chance
if __name__ == sys.main: ...
to execute module in a package that use relative imports.
Ran this PEP past python-ideas. Stopped the discussion there when too
many new ideas were being proposed. =) I have listed all of them in
the Rejected Ideas section, although if overwhelming support for one
comes forward the PEP can shift to one of them.
What is the entry point for your program? Usually the entry point for a program will be at the root of the project. Since it is at the root, all the modules within the root will be importable, provided there is an
__init__.py file in them.
So, using your example:
my_project/ main.py package1/ __init__.py module1 module2 package2/ __init__.py module1 module2
main.py would be the entry point for your program. Because the file that is executed as main is automatically put on the PYTHONPATH, both
package2 are available from the top level import.
# in main.py from package1.module1 import * from package1.module2 import * # in package1.module1 import module2 from package2.module1 import * # in package2.module1 import * import module2 from package1.module1 import *
Note that in the above, package1 and package2 depend on each other. That should never be the case. But this is just an example of being able to import from anywhere.
main.py doesn't have to be anything fancy either. It can be very simple:
# main.py if __name__ == '__main__': from package1.module1 import SomeClass SomeClass().start()
The point I'm trying to make, is that if a module needs to be accessible by other modules, that module should be available as a top level import. A module should not attempt to put itself as a top level import (directly on the PYTHONPATH).
It should be the responsibility of the project for ensuring that all imports can be satisfied if the module is included directly in the project. There are two ways to do this. The first is by creating a bootstrapper file such as
main.py in the project folder. The other, is by creating a file that adds all relevant paths to PYTHONPATH, that is loaded by any entry points that may exist.
# setup.py import sys def load(): paths = ['/path1/','/path2/','/path3/'] for p in path: sys.path.insert(0, p) # entrypoint.py from setup import load load() # continue with program
The main thing to take away, is that a module is not supposed to put itself on the path. The path should be determined automatically by the entry point into the program, or defined explicitly by a setup script that knows where all the relevant modules are.