Differences between revisions 1 and 2
Revision 1 as of 2009-04-05 22:54:14
Size: 3533
Editor: 99-51-74-201
Comment: Is it a sin to omit if __name__ from a Python file?
Revision 2 as of 2009-04-06 02:48:13
Size: 3545
Comment:
Deletions are marked like this. Additions are marked like this.
Line 7: Line 7:
A colleague has recently been thrust into Python programming because we needed to create our own tools around some of the Opsware tools and using their APIs. He recently posed a question: ''Is it a sin to not to include '''if __name__ == '__main__':''' in a Python file?'' A colleague has recently been thrust into Python programming because we needed to create our own tools around some of the Opsware tools and using their APIs. He recently posed a question: ''Is it a sin to not to include {{{if __name__ == '__main__':}}} in a Python file?''
Line 9: Line 9:
As we become accustomed to Python it's easy for us to take the ''if __name__'' convention for granted. My personal opinion is that it belongs in every .py file even if only to serve as a point of documentation (put a ''pass'' statement or print an error message if the file represents code which has no meaningful standalone purpose). However I still wouldn't call it a "sin" to omit it. As we become accustomed to Python it's easy for us to take the {{{if __name__}}} convention for granted. My personal opinion is that it belongs in every .py file even if only to serve as a point of documentation (put a ''pass'' statement or print an error message if the file represents code which has no meaningful standalone purpose). However I still wouldn't call it a "sin" to omit it.
Line 13: Line 13:
''if __name__ == '__main__': '' should be in every Python file with the following possible exeptions: {{{if __name__ == '__main__': }}} should be in every Python file with the following possible exeptions:
Line 22: Line 22:
What if you import a script without an ''if __name__'' line in it? A bunch of unintended activity ... possibly terminating importing script (if sys.exit() was called, for example). This is the one really bad case ... and one which should serve as an object lesson to any Pythonista who imports code without understanding what its supposed to be doing). Notably the code has to be in a file with a .py extension and it has to be on the PYTHONPATH (sys.path) for this failure mode to occur. What if you import a script without an {{{if __name__}}} line in it? A bunch of unintended activity ... possibly terminating importing script (if sys.exit() was called, for example). This is the one really bad case ... and one which should serve as an object lesson to any Pythonista who imports code without understanding what its supposed to be doing). Notably the code has to be in a file with a .py extension and it has to be on the PYTHONPATH (sys.path) for this failure mode to occur.
Line 24: Line 24:
Prepending the whole script with the ''if __name__'' test (and indenting the whole body of code) then renders that error harmless. It runs just fine, and importing it does "nothing." Prepending the whole script with the {{{if __name__}}} test (and indenting the whole body of code) then renders that error harmless. It runs just fine, and importing it does "nothing."
Line 26: Line 26:
In fact one could even add: ''if __name__ '''!=''' '__main__':'' to print an error and call ''sys.exit(1)'' if an attempt is made to import a script that's written purely as an executable. That's perfectly legal. There's nothing magical about ''if __name__ =='' ... it works like any other Python conditional construct. In fact one could even add: {{{if __name__ != '__main__':}}} to print an error and call {{{sys.exit(1)}}} if an attempt is made to import a script that's written purely as an executable. That's perfectly legal. There's nothing magical about {{{if __name__ ==}}} ... it works like any other Python conditional construct.
Line 28: Line 28:
As I was working with Joe (my colleague) I pointed out that it's a bit dubious to write code which is purely executable with no re-usability. I've only see that as very short, one or two line, wrappers which import and call into other Python code. I also pointed out that one can use the ''if __name__'' suite to implement unit tests in files which are (otherwise) purely modules. As I was working with Joe (my colleague) I pointed out that it's a bit dubious to write code which is purely executable with no re-usability. I've only see that as very short, one or two line, wrappers which import and call into other Python code. I also pointed out that one can use the {{{if __name__}}} suite to implement unit tests in files which are (otherwise) purely modules.
Line 30: Line 30:
The key point here is that the purpose of the ''if __name__'' check is to separate reusable code (definitions of classes and functions and initializations of variables) from actions (which use that code). Python's support for it encourages us to make parts of every script we right re-usable and it can encourage us to include unit tests in the same files with code and class definitions. The key point here is that the purpose of the {{{if __name__}}} check is to separate reusable code (definitions of classes and functions and initializations of variables) from actions (which use that code). Python's support for it encourages us to make parts of every script we right re-usable and it can encourage us to include unit tests in the same files with code and class definitions.

Jim Dennis

Is it a sin?

A colleague has recently been thrust into Python programming because we needed to create our own tools around some of the Opsware tools and using their APIs. He recently posed a question: Is it a sin to not to include if __name__ == '__main__': in a Python file?

As we become accustomed to Python it's easy for us to take the if __name__ convention for granted. My personal opinion is that it belongs in every .py file even if only to serve as a point of documentation (put a pass statement or print an error message if the file represents code which has no meaningful standalone purpose). However I still wouldn't call it a "sin" to omit it.

In my response I came up with the following guidelines for him:

if __name__ == '__main__':  should be in every Python file with the following possible exeptions:

* A script NOT ending in .py (can't be accidentally imported it's not strictly needed) * A module which is NOT marked executable (can't be accidentally executed as a script)

Notably, the construct is harmless in both these cases as well. Properly used its inclusion will prevent the two problems that might arise from changes to filenames or permissions.

What if you execute something which is purely a module? "Nothing" happens. (All the definition and initialization code is processed and then the interpreter drops off the end of the file). Appending a warning like: "Nothing to do! This file should be imported." is harmlessly helpful in case someone makes the file executable and someone (possibly someone else) blindly executes it.

What if you import a script without an if __name__ line in it? A bunch of unintended activity ... possibly terminating importing script (if sys.exit() was called, for example). This is the one really bad case ... and one which should serve as an object lesson to any Pythonista who imports code without understanding what its supposed to be doing). Notably the code has to be in a file with a .py extension and it has to be on the PYTHONPATH (sys.path) for this failure mode to occur.

Prepending the whole script with the if __name__ test (and indenting the whole body of code) then renders that error harmless. It runs just fine, and importing it does "nothing."

In fact one could even add: if __name__ != '__main__': to print an error and call sys.exit(1) if an attempt is made to import a script that's written purely as an executable. That's perfectly legal. There's nothing magical about if __name__ == ... it works like any other Python conditional construct.

As I was working with Joe (my colleague) I pointed out that it's a bit dubious to write code which is purely executable with no re-usability. I've only see that as very short, one or two line, wrappers which import and call into other Python code. I also pointed out that one can use the if __name__ suite to implement unit tests in files which are (otherwise) purely modules.

The key point here is that the purpose of the if __name__ check is to separate reusable code (definitions of classes and functions and initializations of variables) from actions (which use that code). Python's support for it encourages us to make parts of every script we right re-usable and it can encourage us to include unit tests in the same files with code and class definitions.

Email: <aswrguy AT SPAMFREE gmail DOT com>

...


CategoryHomepage

JimD (last edited 2009-04-11 23:05:32 by 99-51-74-201)

Unable to edit the page? See the FrontPage for instructions.