If you are a beginner, probably the only answer you need right now is that this code is unnecessary for a simple script. It is only useful if you want to be able to import
your script (or unpickle
etc; see the other answers here for some other non-beginner scenarios).
In slightly different words, the if __name__
guard is a mechanism for hiding code from other code. If you don't have a specific reason to hide something, don't: If you don't need to hide some code from import
, don't put it behind this guard, and if you do, hide as little as possible.
In slightly more detail, let's say you have a simple script fib.py
(adapted from this answer):
# XXX FIXME: useless (see below)
if __name__ == "__main__":
n = int(input('Write a number: '))
a, b = 0, 1
while b < n:
a, b = b, a+b
print('Fibonacci number %i: %i' % (n, b))
Now, if you simply run python fib.py
it works fine. But __name__
will always be "__main__"
in this scenario, so the condition is actually unnecessary. The script could be simplified to just
n = int(input('Write a number: '))
a, b = 0, 1
while b < n:
a, b = b, a+b
print('Fibonacci number %i: %i' % (n, b))
Now, you still can't import fib
with the new version, but if you didn't plan to do that in the first place, this version is actually better, because it's simpler and clearer.
If you do want to be able to import fib
, the first version was useless, too, because the useful code was in a section which will not run when you import
that file (in which case __name__
will not be "__main__"
). The proper design in that case would be to refactor the code so that the useful parts are in a function you can run when you want to after you have import
ed it.
def main():
n = int(input('Write a number: '))
a, b = 0, 1
while b < n:
a, b = b, a+b
print('Fibonacci number %i: %i' % (n, b))
if __name__ == "__main__":
main()
Now, if you import fib
, the call to main()
will not be executed; but when you run python fib.py
, it will.
Actually, a better design still would be to isolate the reusable part (the actual calculation) from the user-visible input/output:
def fibn(n: int) -> int:
a, b = 0, 1
while b < n:
a, b = b, a+b
return b
def main() -> None:
n = int(input('Write a number: '))
print('Fibonacci number %i: %i' % (n, fibn(n)))
if __name__ == "__main__":
main()
Now, you can from fib import fibn
and call the fibn()
function from the code which performs this import
.
(I called the function fibn()
just to make it clearer what is what in this example. In real life, you might call it fib()
and do from fib import fib
.)
Notice the more modular and reusable design; the fibn
function contains the actual calculation, but no user interface parts; and the pesky interactive I/O is separated out into the main
function so that you can bypass it (or call it if you want to, of course).
Returning to the code in the question, I would similarly move the code from the if
into a function as well, so that callers can invoke that function if they want to.
def main():
lock = thread.allocate_lock()
thread.start_new_thread(myfunction, ("Thread #: 1", 2, lock))
thread.start_new_thread(myfunction, ("Thread #: 2", 2, lock))
if __name__ == "__main__":
main()
This changes the scope of the lock
variable; if the surrounding code needs access to it, you will need to make it global
(or, perhaps, better, refactor main
to return lock
, and have the caller capture the value in a local variable of its own).
(Unlike in languages like C, the name main
has no specific meaning to Python; but it's a common convention to use it as the name of the thing which will be run. You still have to actually explicitly call it, like main()
, unlike in C.)
if __name__
check only runs when it's invoked as a command, not when imported. It's also useful if you want to debug a Python script using an interactive Python session. You can "import" code that's normally run as a command in an interactive session, then manually enter code to run functions/classes in the script as you like.