Why does two main functions in a single Python script work?
Question:
I was trying to do silly things in Python and tried the silliest of the things (see below) to see how Python reacts. To my surprise it executed perfectly. But I do not understand why.
How does Python know which foo
to execute? Why does it not execute the same foo
twice?
def main():
foo()
def foo():
print('this is foo 1.')
if __name__ == '__main__':
main()
def main():
foo()
def foo():
print('this is foo 2.')
if __name__ == '__main__':
main()
Answers:
Python executes statements from top to bottom as they appear in the input file.
So first it defines two functions main
and foo
and then calls main
, leading to the output from foo
, "this is foo 1".
Then it defines two other functions which happen to be also named main
and foo
, these names now refer to the new functions and the first two functions are no longer accessible by these names. You could also say that the new functions override the old functions or that they are redefined.
Then it calls main
(which now refers to the new function) which leads to the output of the new function foo
, "this is foo 2".
Also note that the function name main
has no special meaning in Python.
When main
is called the first time, foo is the function that prints "This is foo 1.". When main
is called the second time, foo is the function that prints "This is foo 2." Therefore, the first time, "This is foo 1." is the output, and the second time, "This is foo 2." is the output.
Python is in interpretted language so it executes each line as it encounters it.
Which means if you ran this on the python shell or as a script your output would be determined by whatever is encountered first foo() – foo1, and then the newer value of the function foo() – foo2
Output:
this is foo 1.
this is foo 2.
The interpreter does these things, in the order they appear in the file:
-
Defines main
as your first definition of that function.
-
Defines foo
as your first definition of that function.
-
Because __name__
is __main__
: executes the function (currently defined as main
) which calls the function currently defined as foo
.
-
Redefines main
as your second definition of that function. (Albeit that’s no different from the first definition.)
-
Redefines foo
as your second definition of that function.
-
Because __name__
is __main__
: executes the function (currently defined as main
) which calls the function currently defined as foo
, which by now is your second foo
.
You might be assuming that the interpreter somehow does a "first pass" and processes all function definitions, and only then executes the code under if __name__ == '__main__'
. But that’s not how it works. The steps are executed in order, like they would be if you ran:
x = 5
y = 7
print(x+y)
x = 6
y = 10
print(x+y)
For similar reasons, this code would not work:
if __name__ == '__main__':
foo()
def foo():
print(2)
because foo
is undefined at the point it is referenced.
I was trying to do silly things in Python and tried the silliest of the things (see below) to see how Python reacts. To my surprise it executed perfectly. But I do not understand why.
How does Python know which foo
to execute? Why does it not execute the same foo
twice?
def main():
foo()
def foo():
print('this is foo 1.')
if __name__ == '__main__':
main()
def main():
foo()
def foo():
print('this is foo 2.')
if __name__ == '__main__':
main()
Python executes statements from top to bottom as they appear in the input file.
So first it defines two functions main
and foo
and then calls main
, leading to the output from foo
, "this is foo 1".
Then it defines two other functions which happen to be also named main
and foo
, these names now refer to the new functions and the first two functions are no longer accessible by these names. You could also say that the new functions override the old functions or that they are redefined.
Then it calls main
(which now refers to the new function) which leads to the output of the new function foo
, "this is foo 2".
Also note that the function name main
has no special meaning in Python.
When main
is called the first time, foo is the function that prints "This is foo 1.". When main
is called the second time, foo is the function that prints "This is foo 2." Therefore, the first time, "This is foo 1." is the output, and the second time, "This is foo 2." is the output.
Python is in interpretted language so it executes each line as it encounters it.
Which means if you ran this on the python shell or as a script your output would be determined by whatever is encountered first foo() – foo1, and then the newer value of the function foo() – foo2
Output:
this is foo 1.
this is foo 2.
The interpreter does these things, in the order they appear in the file:
-
Defines
main
as your first definition of that function. -
Defines
foo
as your first definition of that function. -
Because
__name__
is__main__
: executes the function (currently defined asmain
) which calls the function currently defined asfoo
. -
Redefines
main
as your second definition of that function. (Albeit that’s no different from the first definition.) -
Redefines
foo
as your second definition of that function. -
Because
__name__
is__main__
: executes the function (currently defined asmain
) which calls the function currently defined asfoo
, which by now is your secondfoo
.
You might be assuming that the interpreter somehow does a "first pass" and processes all function definitions, and only then executes the code under if __name__ == '__main__'
. But that’s not how it works. The steps are executed in order, like they would be if you ran:
x = 5
y = 7
print(x+y)
x = 6
y = 10
print(x+y)
For similar reasons, this code would not work:
if __name__ == '__main__':
foo()
def foo():
print(2)
because foo
is undefined at the point it is referenced.