Suppose I have the following simple project structure.
project/
package/
__init__.py
__main__.py
module.py
requirements.txt
README.md
After doing some research on Google, I've tried to make it reflect general best practices for a very simple console application (but not as simple as simply having a single script). Suppose __init__.py contains simply print("Hello from __init__.py") and module.py contains a similar statement.
How should I do imports inside of __main__.py, and then how should I run my project?
Let's say first that __main__.py looks simply like this:
import module
print("Hello from __main__.py")
If I run my project with the simple command python package, I get this output:
Hello from module.py
Hello from __main__.py
As can be seen, __init__.py didn't run. I think this is because I'm running my project's package as a script. If I instead run it as a module with the command python -m package I get this output:
Hello from __init__.py
Traceback (most recent call last):
File "C:\Users\MY_USER\AppData\Local\Programs\Python\Python38\lib\runpy.py", line 194, in _run_module_as_main
return _run_code(code, main_globals, None,
File "C:\Users\MY_USER\AppData\Local\Programs\Python\Python38\lib\runpy.py", line 87, in _run_code
exec(code, run_globals)
File "C:\Users\MY_USER\PATH\TO\PROJECT\project\package\__main__.py", line 1, in <module>
import module
ModuleNotFoundError: No module named 'module'
If I change the first line in __main__.py to import package.module and run python -m package again I get this output:
Hello from __init__.py
Hello from module.py
Hello from __main__.py
Great! It seems everything runs properly now when running my project's package as a module. Now what if I try python package again and run it as a script?
Traceback (most recent call last):
File "C:\Users\MY_USER\AppData\Local\Programs\Python\Python38\lib\runpy.py", line 194, in _run_module_as_main
return _run_code(code, main_globals, None,
File "C:\Users\MY_USER\AppData\Local\Programs\Python\Python38\lib\runpy.py", line 87, in _run_code
exec(code, run_globals)
File "package\__main__.py", line 1, in <module>
import package.module
ModuleNotFoundError: No module named 'package'
Alright. So please correct me if I'm wrong, but it seems that I have two options. I can either write the imports in my package to work with running it as a script or running as a module, but not both. Which is better, if one is indeed preferable, and why? When would you use the command python package vs python -m package, and why? Is there some general rule for writing imports within a simple project that I might not be understanding? Am I missing something else fundamental?
In summary: What is the best practice in this situation, why is it the best practice, and when would you set your project up for the alternative approach (python package vs python -m package)?