how do I determine whether a python script is imported as module or run as script?

Viewed 11695

The question is rather straightforward but not answered by searching. How do I determine in a python script whether this script is imported as a module or run as a script? Is there a difference at all in python?

The problem is, that I want to evaluate the command line parameters only if run as a script, but not if the module is only imported to use it in another script. (I want to be able to use one script as both library and program.) I am afraid the vanilla way would be to build the lib and a second script that uses it, but I'd like to have a second option for small tool/libs.

2 Answers

As pointed out by @bobince:

You will also be __main__ if you are a module invoked by python -m somemodule

Let's suppose you have a Python file bar.py and an empty __init__.py, both inside a folder called foo:

$ tree
.
└── foo
    ├── __init__.py
    └── bar.py

$ cat foo/__init__.py

The Python code blocks below are the content of foo/bar.py.

Using __name__ (not working)

print('Code executed as a %s' % 'script' if __name__ == '__main__' else 'module')

This will produce:

$ python foo/bar.py
Code executed as a script

$ python -m foo.bar
Code executed as a script

Solution 1: using vars() and sys.modules

import sys
mod_name = vars(sys.modules[__name__])['__package__']
print('Code executed as a ' + ('module named %s' % mod_name if mod_name else 'script'))

This will produce:

$ python foo/bar.py
Code executed as a module named foo

$ python -m foo.bar
Code executed as a script

Solution 2: Using a try-except block on module import

import sys
try:
    import foo
    print('Code executed as a module')
except ImportError:
    print('Code executed as a script')
    # Code will fail here, but you can still print a comprehensive error message before exiting:
    print('Usage: python -m foo.bar')
    sys.exit()

This will produce:

$ python foo/bar.py
Code executed as a module

$ python -m foo.bar
Code executed as a script
Usage: python -m foo.bar
Related