4

I am learning main and explore its applications with codes:

a = 1
b = 2

def main():
    x = add(a, b)
    print(x)

if __name__ == "__main__":
    main()

def add(a, b):
    a = a + 1
    return a + b

However, it report NameError:

In [87]: run test.py                                                                                              
---------------------------------------------------------------------------
NameError   Traceback (most recent call last)

NameError: name 'add' is not defined

Re-position if __name__ == "__main__": to end is a solution,

a = 1
b = 2

def main():
    x = add(a, b)
    print(x)

def add(a, b):
    a = a + 1
    return a + b

if __name__ == "__main__":
    main()
In [88]: run test.py                                                                                              
4

I am confused about why the previous case failed.

if __name__ == "__main__": invoke main, main invoke add.

AbstProcDo
  • 19,953
  • 19
  • 81
  • 138

2 Answers2

7

Everything is done in order in Python, top to bottom.

a = 1  # assigns 1 -> a
b = 2  # assigns 2 -> b

def main():  # main is defined
    # body of main, not executed until it's called.

if __name__ == "__main__":  # it does! Let's enter the block
    main()  # let's run main, so we have to look back at that block we skipped earlier...

    # from above
    x = add(a, b)  # call add....oh wait -- WHAT'S add?!

In the bottom example, add is defined before main is executed, so main knows what to do when you call x = add(a, b).

Adam Smith
  • 52,157
  • 12
  • 73
  • 112
  • so if there's a executing line, codes after it will be ignored? – AbstProcDo Oct 23 '18 at 06:11
  • The line of execution runs top to bottom. When it hits the line that calls main, it executes the code in `main`'s function body. That code calls `add`, but in your top example, the line of execution hasn't gotten to the definition of `add` yet (because it's below the call to `main`) so `main` has no way to know what `add` is. – Adam Smith Oct 23 '18 at 06:36
  • ty, I got it. invoke add(a, b), ahead of define it. – AbstProcDo Oct 23 '18 at 06:57
5

Python effectively runs lines of code as it reads them from the file. (Not really, but for purposes of this question, it acts as if it does.) So when this piece of code runs:

if __name__ == "__main__":
    main()

in your first code sample, the add function has not yet been defined. That only happens when Python encounters the def add(...): block. Since main() calls add(), Python complains that an undefined name (add) is being used.

When you move the def add(...): block up before the call to main(), then the definition of add() happens before main() runs, so everything is fine.

David Z
  • 128,184
  • 27
  • 255
  • 279