2

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.

Charles Duffy
  • 280,126
  • 43
  • 390
  • 441
D. W.
  • 163
  • 1
  • 2
  • 9
  • There's nothing odd whatsoever about the `sys.exit()`, and we already have (answered!) questions in our knowledgebase about the practices used there, comparing `__name__` to `__main__`. Please consider narrowing your question to no longer have a duplicative component; arguably, spanning both pre-answered and non-answered questions makes it "too broad". – Charles Duffy Jan 04 '17 at 22:06
  • ...one example among many: [Why use `def main()`?](http://stackoverflow.com/questions/4041238/why-use-def-main) – Charles Duffy Jan 04 '17 at 22:09

3 Answers3

2

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

Uriel
  • 15,579
  • 6
  • 25
  • 46
  • Hmmm... Interesting. The original code does not use `sys.arvg[0]` at all, or any of the elements of argv, in the `main()` function. If this function was run as a module instead of out of the command line, would defining argv like this ensure that the main() function always uses the arguments specific in the command line argument of the script that is calling this as a module? – D. W. Jan 04 '17 at 22:13
  • If the function doesn't use `argv`, then it has no meaning for the use of it as a parameter. Otherwise, you can control the main functionality by sending in your custom parameters (or ensuring they will exist with the default `argv`) – Uriel Jan 04 '17 at 22:40
1

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()
Robᵩ
  • 163,533
  • 20
  • 239
  • 308
0

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.

Barmar
  • 741,623
  • 53
  • 500
  • 612