Why def main(argv=[__name__]) and if __name__ == "__main__": sys.exit(main(sys.argv))?

7.3k Views Asked by At

I'm working with/rewriting a code that first defines a function as follows:

def main(argv=[__name__]):
    ...
    *rest of code*
    ...

and ends with:

if __name__ == "__main__":
    sys.exit(main(sys.argv))

I'm under the impression that what this is doing is checking to make sure that the script is being executed from the command line, and then running the function main with the arguments provided as it exits python. But then, why is it necessary to preset the variable argv to [__name__] in the function definition? This is not my code, so I don't know the original intention behind this. I am, however, new to using if __name__ == "__main__": lines to spot check command line execution, so maybe there is some glaringly obvious reason for this syntax that I'm missing. Any help, or further detail on main function definition and argument/command-line-vs-module testing would be appreciated.

3

There are 3 best solutions below

0
On

The main() definition allows for the possibility that main() will be called in other ways than the sys.exit() line at the bottom of the file. This might be an example of defensive programming, or it might indicate other supported uses of this file.

One such other supported use might be to invoke it from another Python program, like so:

import your_module
your_module.main()
2
On

As for the argv=[__name__], the original dev probably wanted to keep the option to run this function not from the command line (i.e. invoked by another module), and provided __name__ because it uses sys.argv[0] for some functionality.

The main function is nothing to do with python, just some convention (derived from languages like C). sys.exit(main(sys.argv)) will trigger the sys.exit function with an exit code equivalent to the product of running the main function with the received command line arguments. main probably should return an appropriate exit code (0 is to indicate OK, others imply various exceptions).

0
On

When a script is run from the CLI, argv[0] is the name of the script, and the rest of argv is the command-line arguments. So the rest of main() may expect that argv[0] will always be filled in.

The default value is ensuring that argv[0] has something analogous in it when the file is being imported instead of being run directly. In this case, it's the name of the module.