The literal code as you have it no, as it's useless. pass
is a keyword to "do nothing" and the interpreter will need to evaluate the condition first, so it's literally "check if running directly, then do nothing" which is almost equal to not having those two lines there at all and if excluding the condition check being evaluated it's equal to being a comment or not being present at all.
>>> import dis
>>> dis.dis("") # no code to evaluate, just the default behavior
1 0 LOAD_CONST 0 (None)
2 RETURN_VALUE
>>> dis.dis("pass") # does nothing and/or is stripped away by the parser/compiler
1 0 LOAD_CONST 0 (None)
2 RETURN_VALUE
>>> dis.dis("""
... if __name__ == "__main__":
... pass
... """)
2 0 LOAD_NAME 0 (__name__)
2 LOAD_CONST 0 ('__main__')
4 COMPARE_OP 2 (==)
6 POP_JUMP_IF_FALSE 8
3 >> 8 LOAD_CONST 1 (None)
10 RETURN_VALUE
If it's meant not in literal sense but a question of whether each of your modules should have a __main__
guard, it depends on your code/logic. In the end, even an import is a code (unlike #include
in C/C++ which in simple terms copy-pastes the full file in its place) and it needs to run so the module is executed and ready for loading somewhere else.
The point of the guard is a very different thing. It prevents executing code which you or your users consider bad when executed such as trying to connect to a database in cases when there's none or when running a test suite, when using global variables which you want present conditionally or any other case you might want to have.
The guard, however, isn't supposed to prevent the normal Python behavior, that is, CPython interpreter reading the text file .py
, parsing the text, compiling something in between, loading the scopes and perhaps making ready for using by some other module.
Making this might or might not make sense:
import sys
if __name__ == "__main__":
# import and print only when executing, not when importing
from mymodule.submodule import something
print(something(), file=sys.stderr)
vs
import sys
# happens always
from mymodule.submodule import something
print(something(), file=sys.stderr)
Why the example with an import? Because an import
or from ... import ...
statement also executes a code. Let's say you have a print("Hello")
in a submodule, then from mymodule.submodule import something
will parse and load the submodule.py
(or submodule/__init__.py
/ mymodule/submodule.py
), execute all of its code such as import
s, class
es, def
s to even create the objects for you to reference later on when importing them.
One can write a class with an undesired effect too:
class My:
print("Hello")
and that will also be executed when something is imported from a module containing this code. It's also a context when class variables are evaluated, so trying to connect to a DB in that scope is also annoying to encounter, yet might have its use-case.
Therefore there's not a question of "should" but it's more of a politeness or correctness not to cause unexpected or annoying things for you, your test suite or your users whether it's an application or a library what you are creating.
And you can also introduce examples or tests at the end of a library's module too, which may also be considered a fair use of the __main__
guard yet a completely unnecessary step for some:
class Square:
def __init__(self):
print(f"I am a {self.__class__.__name__}")
@property
def is_shape(self):
return True
if __name__ == "__main__":
square = Square()
assert square.is_shape
The __main__
guard can be found since CPython 1.0
A module can now find its own name by accessing the global variable __name__
. Assigning to this variable essentially renames the module (it should also be stored under a different key in sys.modules
). A neat hack follows from this: a module that wants to execute a main program when called as a script no longer needs to compare sys.argv[0]
; it can simply do "if __name__ == '__main__': main()
". (1994, source)
As for the related PEPs, it's a bit hard here as the original functionality is present since CPython 1.0.0 and the PEPs are only slightly relevant in the sense that they touch the topic of __name__
variable being present or somehow set: