Execution of Python code with -m option or not
The python interpreter has
-m module option that "Runs library module module as a script".
With this python code a.py:
if __name__ == "__main__": print __package__ print __name__
python -m a to get
"" <-- Empty String __main__
python a.py returns
None <-- None __main__
To me, those two invocation seems to be the same except package is not None when invoked with -m option.
python -m runpy a, I get the same as
python -m a with python module compiled to get a.pyc.
What's the (practical) difference between these invocations? Any pros and cons between them?
Also, David Beazley's Python Essential Reference explains it as "The -m option runs a library module as a script which executes inside the main module prior to the execution of the main script". What does it mean?
When you use the
-m command-line flag, Python will import a module or package for you, then run it as a script. When you don't use the
-m flag, the file you named is run as just a script.
The distinction is important when you try to run a package. There is a big difference between:
python -m foo.bar.baz
as in the latter case,
foo.bar is imported and relative imports will work correctly with
foo.bar as the starting point.
$ mkdir -p test/foo/bar $ touch test/foo/__init__.py $ touch test/foo/bar/__init__.py $ cat << EOF > test/foo/bar/baz.py > if __name__ == "__main__": > print __package__ > print __name__ > > EOF $ PYTHONPATH=test python test/foo/bar/baz.py None __main__ $ PYTHONPATH=test bin/python -m foo.bar.baz foo.bar __main__
As a result, Python has to actually care about packages when using the
-m switch. A normal script can never be a package, so
__package__ is set to
But run a package or module inside a package with
-m and now there is at least the possibility of a package, so the
__package__ variable is set to a string value; in the above demonstration it is set to
foo.bar, for plain modules not inside a package, it is set to an empty string.
As for the
__main__ module ; Python imports scripts being run as it would a regular module. A new module object is created to hold the global namespace, stored in
sys.modules['__main__']. This is what the
__name__ variable refers to, it is a key in that structure.
For packages, you can create a
__main__.py module and have that run when running
python -m package_name; in fact that's the only way you can run a package as a script:
$ PYTHONPATH=test python -m foo.bar python: No module named foo.bar.__main__; 'foo.bar' is a package and cannot be directly executed $ cp test/foo/bar/baz.py test/foo/bar/__main__.py $ PYTHONPATH=test python -m foo.bar foo.bar __main__
So, when naming a package for running with
-m, Python looks for a
__main__ module contained in that package and executes that as a script. It's name is then still set to
__main__, and the module object is still stored in
★ Back to homepage or read more recommendations: