prosseek prosseek - 6 months ago 32
Python Question

Execution of Python code with -m option or not

The python interpreter has

module option that "Runs library module module as a script".

With this python code

if __name__ == "__main__":
print __package__
print __name__

I tested
python -m a
to get

"" <-- Empty String


None <-- None

To me, those two invocation seems to be the same except __package__ is not None when invoked with -m option.

Interestingly, with
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 foo/bar/


python -m

as in the latter case, is imported and relative imports will work correctly with as the starting point.


$ mkdir -p test/foo/bar
$ touch test/foo/
$ touch test/foo/bar/
$ cat << EOF > test/foo/bar/ 
> if __name__ == "__main__":
>     print __package__
>     print __name__
$ PYTHONPATH=test python test/foo/bar/ 
$ PYTHONPATH=test bin/python -m

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 None.

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, 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 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
python: No module named; '' is a package and cannot be directly executed
$ cp test/foo/bar/ test/foo/bar/
$ PYTHONPATH=test python -m

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 sys.modules['__main__'].