3

I had the impression that the code only below name='main' is executed if you run a module directly. However, I saw a line mr = MapReduct.MapReduce() appearing above that statement? How is that executed and what is the reason one would put it above the if clause?

import MapReduce
import sys

"""
Word Count Example in the Simple Python MapReduce Framework
"""

mr = MapReduce.MapReduce()

if __name__ == '__main__':
  inputdata = open(sys.argv[1])
  mr.execute(inputdata, mapper, reducer)
chepner
  • 497,756
  • 71
  • 530
  • 681
vkaul11
  • 4,098
  • 12
  • 47
  • 79
  • 1
    The stuff above `if __name__ == '__main__':` is always executed. Stuff inside the `if` is only executed if the module is run directly. – Blorgbeard Jun 11 '13 at 22:55

3 Answers3

4

Of course, all the code before if __name__ == '__main__': gets executed. A script is processed from top to bottom, and each expression or statement that's found is executed in order. But the if __name__ == '__main__': line is special: it'll get run if the script is called from the command line.

By convention, the if __name__ == '__main__': line is put at the end, to make sure that all the code that it depends on has been evaluated up to this point.

Take a look at this other question to understand what's happening in that line.

Community
  • 1
  • 1
Óscar López
  • 232,561
  • 37
  • 312
  • 386
  • Why would one put the code above the if clause and not after it? Maybe because you want that code to be executed even if the module is called externally? – vkaul11 Jun 11 '13 at 22:57
  • @vkaul11 yes, that's how the `if __name__ ...` line works: it's the part that will start the execution when the script is called from the command line, and you have to make sure that all the other definitions in the script have been evaluated up to this point. See the link I posted in my answer for more details – Óscar López Jun 11 '13 at 22:59
3

Everything in the file is executed, but most of what you put above __name__ == '__main__' is just function or class definitions - executing those just define a function or class and don't produce any noticeable side effects.

If you put a print statement in the file outside of those definitions for example, you'll see some output.

Mark Ransom
  • 299,747
  • 42
  • 398
  • 622
  • Yes that is what I was used to Mark, so I was not expecting any code that actually does object construction above the if statement. Therefore, it caught me by surprise that why someone will do that. – vkaul11 Jun 11 '13 at 22:58
  • @vkaul11: it's worth noting that function and class definitions are *also* executable statements. `def fn(): ...` is executed and has the effect of placing `fn` into the module name-space. If your example is named `example.py`, after `import example`, the `mr = ...` line creates something named `example.mr`. The `import`s are also executed and create the names `example.MapReduce` and `example.sys`. – torek Jun 11 '13 at 23:34
2

Yes, The entire script is executed.

The reason we have a main guard is to enable your program to be used both as a standalone script ( in which case the __name__ variable is defined as "__main__") or imported as a module from another python script. In this case, we don't want any code to be run, we just want definitions of the code to be available to whoever loaded us.

One typical use of the __main__ guard is to run unit tests if the python file is run on its own. For example let us imagine we have file mymodule.py:

def my_function(foo):
  """This function will add 54 to foo.
  The following two lines are 'doctests' and can be run 
  automatically to show that the module's function work as expected.
  >>> my_function(6)
  60
  """
  return foo + 54

if __name__ == "__main__":
  import doctest
  doctest.testmod() # this will run all doctests in this file

If we now run this on the command line, the tests will be run to check that the module works as expected.

Now, from another file, or from the command line, we can import mymodule.py:

>>> import mymodule # Note that the tests will not be run when importing
>>> mymodule.my_function(3)
57

And the tests will not run because the __name__ variable will not be __main__ when the script is imported.

You can test this with a simple file (test.py):

➤ cat test.py
#!/usr/bin/env python
print("my name is: ", __name__)    
➤ python test.py 
my name is:  __main__
➤ python
Python 3.3.1 (default, Apr  6 2013, 19:11:39) 
[GCC 4.8.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import test
my name is:  test
>>> 
brice
  • 24,329
  • 7
  • 79
  • 95