What is this code actually doing?
When you execute xy.py, you import ab. The import statement runs the module on import, so ab's operations get executed before the remainder of xy's. Once finished with ab, it continues with xy.
The interpreter keeps track of which scripts are running with __name__
. When you run a script - no matter what you've named it - the interpreter calls it "__main__"
. That's how it keeps track of which script is the master file, the script that gets returned to after an external call to another script. (The 'home' script, you might say.)
Any other script that's called from this 'main' script is assigned its filename as its __name__
. Hence, the line if __name__ == "__main__" :
is the interpreter's test to determine if it's running on the script it's looking at (parsing), or if it's temporarily peeking into another script. This gives the programmer flexibility to have the script behave differently if it's called externally.
To understand what's happening, focus first on the unindented lines and the order they appear in the scripts. Remember that function - or def
- blocks don't do anything by themselves until they're called. What the interpreter might think if mumbled to itself:
- Open xy.py.
- Import and open file with the
__name__
ab.py.
- Oh, a function. I'll remember that.
- Ok, function a(); I just learned that. I guess I'll print now.
- End of file; back to
'__main__'
!
- Oh, a function. I'll remember that.
- Another one.
- Function x(); ok, printing 's'.
- What's this? An
if
statement. Well, the condition has been met (the variable __name__
has been set to '__main__'
), so I'll print 'b function'.
However, I don't think you're using it properly. There are probably exceptions, but the bottom two lines should be:
if __name__ == "__main__":
main()
... which means "If this is the 'main' or home script, execute the function called main()
. That's why you'll see a def main():
block up top, which contains the main flow of the script's functionality.
Why do we implement this?
Remember what I said earlier about import statements? When you import a module it doesn't just 'recognize' it and wait for further instructions. It actually runs all the executable operations contained within the script. So, putting the meat of your script into the main()
function effectively quarantines it, putting it in isolation, so that it can't immediately run when imported by another script.
Again, there will be exceptions, but common practice is that main()
doesn't usually get called externally. So you may be wondering one more thing: if we're not calling main()
, why are we calling the script at all? It's because many people structure their scripts with stand-alone functions that are built to be run by themselves. They're then later called somewhere else in the body of the script. Which brings me to this:
Our code is work without it also
Yes, you're right. These separate functions can be called from an in-line script that's not contained inside a main()
function. If you're accustomed (as I am, in my early learning stages of programming) to building in-line scripts that do exactly what you need, and you'll try to figure it out again if you ever need that operation again - well, you're not used to this kind of internal structure to your code, because it's more complicated to build, and it's not as intuitive to read.
But that's a script that probably can't have its functions called externally, because if it did it would start calculating and assigning variables. And chances are if you're trying to reuse a function, your new script is related closely enough to the old one that there could be conflicting variables.
I should say as an aside, this question contains an answer by kindall that finally helped me to understand - the why, not the how. Unfortunately it's been marked as a duplicate of this one, which I think is a mistake. (I'm new to this site so can't flag it yet; if you agree with me, please flag it for further mod attention.)