Why use def main()? [duplicate]
Asked Answered
A

5

615

I've seen some code samples and tutorials that use

def main():
    # my code here

if __name__ == "__main__":
    main()

But why? Is there any reason not do define your functions at the top of the file, then just write code under it? ie

def my_function()
    # my code here

def my_function_two()
    # my code here

# some code
# call function
# print(something)

I just wonder if there is any rhyme to the main?

Alternant answered 28/10, 2010 at 8:54 Comment(6)
See https://mcmap.net/q/12868/-what-does-if-__name__-quot-__main__-quot-doGermann
https://mcmap.net/q/12868/-what-does-if-__name__-quot-__main__-quot-do does not answer the whole question.Backsaw
What the supposed duplicate doesn't answer: having a main() function (instead of just writing all the code into the "if name" block) is useful because it avoids accidentally creating global variables that could affect other functions.Obla
As well as the other answers, having an entry point for execution of your code enables using entry points in your setup.py to automatically produce executable scripts which wrap the import-and-execute steps. Which is nice when you want your user to be able to write setup-my-app ... rather than python2.7 /opaque/path/to/module.py ...Unsegregated
The downside of doing this is now my code has tons of "global" declaration sitting at the top of "def main()" for every CONSTANT which is set by main(). This looks unprofessional (to me at least).Cheatham
Not a duplicate!!!Devaluate
C
673

Without the main sentinel, the code would be executed even if the script were imported as a module.

Chemotherapy answered 28/10, 2010 at 8:56 Comment(2)
Also worth noting that having a main() function makes it possible to run that code with: import module; module.main(). If the code were just in the if block, it couldn't be run from elsewhere.Danettedaney
Why does python not support a professional main() function which is automatically executed by python code.py?Imponderable
V
267

Everyone else has already answered it, but I think I still have something else to add.

Reasons to have that if statement calling main() (in no particular order):

  • Other languages (like C and Java) have a main() function that is called when the program is executed. Using this if, we can make Python behave like them, which feels more familiar for many people.

  • Code will be cleaner, easier to read, and better organized. (yeah, I know this is subjective)

  • It will be possible to import that python code as a module without nasty side-effects.

  • This means it will be possible to run tests against that code.

  • This means we can import that code into an interactive python shell and test/debug/run it.

  • Variables inside def main are local, while those outside it are global. This may introduce a few bugs and unexpected behaviors.

But, you are not required to write a main() function and call it inside an if statement.

I myself usually start writing small throwaway scripts without any kind of function. If the script grows big enough, or if I feel putting all that code inside a function will benefit me, then I refactor the code and do it. This also happens when I write bash scripts.

Even if you put code inside the main function, you are not required to write it exactly like that. A neat variation could be:

import sys

def main(argv):
    # My code here
    pass

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

This means you can call main() from other scripts (or interactive shell) passing custom parameters. This might be useful in unit tests, or when batch-processing. But remember that the code above will require parsing of argv, thus maybe it would be better to use a different call that pass parameters already parsed.

In an object-oriented application I've written, the code looked like this:

class MyApplication(something):
    # My code here

if __name__ == "__main__":
    app = MyApplication()
    app.run()

So, feel free to write the code that better suits you. :)

Vindicable answered 28/10, 2010 at 10:0 Comment(1)
One benefit of calling main with sys.argv as a parameter as shown here is that this approach works well with the argparse module (which, IMO, is the Right Way to handle command-line arguments). All you need to do differently is pass argv to parse_args in main.Convexoconcave
A
93

if the content of foo.py

print __name__
if __name__ == '__main__':
    print 'XXXX'

A file foo.py can be used in two ways.

  • imported in another file : import foo

In this case __name__ is foo, the code section does not get executed and does not print XXXX.

  • executed directly : python foo.py

When it is executed directly, __name__ is same as __main__ and the code in that section is executed and prints XXXX

One of the use of this functionality to write various kind of unit tests within the same module.

Arbe answered 28/10, 2010 at 8:57 Comment(0)
B
23

"What does if __name__==“__main__”: do?" has already been answered.

Having a main() function allows you to call its functionality if you import the module. The main (no pun intended) benefit of this (IMHO) is that you can unit test it.

Backsaw answered 28/10, 2010 at 8:59 Comment(2)
2 questions having the same answer doesnt make them duplicatesAlpers
@bubakazouba: I agree. I didn't mark this question as a duplicate. A part of this question has a really good answer, I saw no point in duplicating the answer. I answered the rest of the question.Backsaw
V
8

Consider the second script. If you import it in another one, the instructions, as at "global level", will be executed.

Vasiliki answered 28/10, 2010 at 8:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.