My Photo

Become a Fan

AddThis Feed Button

Your email address:


Powered by FeedBlitz

Blog powered by Typepad
Member since 02/2004
Related Posts with Thumbnails

« PRP, Regenokine & other biologic medicine treatments for joint & tendon problems | Main | How to Prevent a JList in a JScrollPane on a JPanel from Resizing »

TrackBack

TrackBack URL for this entry:
http://www.typepad.com/services/trackback/6a00d8341bf70f53ef0168eafce3e9970c

Listed below are links to weblogs that reference def main() in Python considered harmful:

Comments

Feed You can follow this conversation by subscribing to the comment feed for this post.

Dom

It's a bit old, but Guido actually uses this pattern in an example of argument parsing from the command line. So, it can't be that bad, right? ;)

http://www.artima.com/weblogs/viewpost.jsp?thread=4829

Joe McCarthy

Hmm, that certainly is a reputable source.

It seems like the original post, and several followup comments, are focused on parsing arguments, and I wonder whether the potential reduction in code complexity through the use of the argparse module would reduce the need to shuttle so much code off to a main() function ... and thereby reduce the need for main().

Yogi

I've never considered main functions to be bad practice, nor have I come across anyone who's argued it is (I don't see where Code like a Pythonista says it's unpythonic).

In general, wildcard imports shouldn't be used — your example is spot-on. But when they are, it's the programmers responsibility to ensure they're not shooting themselves in the foot.

That said, a simple "fix" for this would be to name the main function _main instead. The single underscore tells python not to include it in wildcard imports. If, for some reason, _main needs to be imported, it can be pulled in explicitly with a from foo import _main. It's also convention to prefix a variable with a single underscore when you want to indicate that it's "private". Of course, nothing in Python is really private, it's just a way of telling other coders, "hey, don't mess with this".

There are also double underscore name mangling tricks, as well as __all__ to explicitly identify what's allowed to be wildcard imported:

http://docs.python.org/tutorial/classes.html#private-variables-and-class-local-references
http://docs.python.org/tutorial/modules.html#importing-from-a-package

Joe McCarthy

Well, it wouldn't be the first time I've unwittingly taken a minority position on an issue.

I like the suggestion using a single underscore prefix in defining _main, as that would more properly designate it as a function not intended to be called from outside the module. Of course, that further highlights the contrivance of my example, where I explicitly call main().

I suppose my lingering discomfort with main() - or _main() - has to do with the mapping of required practices in one language into another language where it is not required. One cannot compile a C++ or Java program without a main() function, but a Python program without main() will run just fine.

Years ago, when I was programming in LISP at UMass, I never defined a main function nor did I ever encounter a LISP program written by anyone else that included such a function. This was before Java was invented, and before C++ had become so prominent, but C - which also requires main() - was in widespread use at the time.

Peter Norvig has highlighted the many similarities between Python and LISP - noting "Python can be seen as a dialect of Lisp with 'traditional' syntax" - and I imagine it's this LISP bias that may be responsible for my "we don't need no stinkin' main()" attitude.

In any case, I'm grateful for the opportunity to continue my education here.

Seanjensengrey

Having a main function is bad per se, I myself use them although with a signature that makes it callable as a module level function.

if __name__ == "__main__":
    main(sys.argv[1:])

It is really nice to be able to run python code inprocess w/o having to shell out. If main() assumes it takes its parameters from sys.argv it effectively makes the code non-callable at the module level. Passing the name of the executable shouldn't be part of the calling convention, hence the slice.

Now instead of calling the entry point `main`, it could have a more descriptive name ...

Joe McCarthy

I like the idea of being able to access the same capability whether the module is invoked as a script (e.g., from the command line) or from within the interpreter ... and like using a more descriptive name (i.e., not "main") for that capability even better.

Jeff Tratner

Just wanted to add another example: Google App Engine also uses main() explicitly for caching I'd argue that the issue that you've highlighted is less about main() as an unpythonic import from Java/C and more about how you should be careful with using wildcard imports in Python, parrticularly in modules that don't define __all__ ( as the Python docs suggest )

Joe McCarthy

@Jeff: thanks for the additional data (or, perhaps, code) point

Skwurlgrrl

Here's a good reason to wrap your code inside a function, whether it's main or not: It pollutes the global namespace if it's not inside a function or class, which (IMHO) is just bad practice, and it can lead to some expected situations where you accidentally reference something external to your class or function, instead of something internal.

I personally use main due to history with C, but wrapping it in a function or class is still a good idea. I do the same with perl - I've seen too much code with functions, classes, and top-level code mixed together.

Skwurlgrrl

... unexpected

Verify your Comment

Previewing your Comment

This is only a preview. Your comment has not yet been posted.

Working...
Your comment could not be posted. Error type:
Your comment has been saved. Comments are moderated and will not appear until approved by the author. Post another comment

The letters and numbers you entered did not match the image. Please try again.

As a final step before posting your comment, enter the letters and numbers you see in the image below. This prevents automated programs from posting comments.

Having trouble reading this image? View an alternate.

Working...

Post a comment

Comments are moderated, and will not appear until the author has approved them.

Photos

  • www.flickr.com
    This is a Flickr badge showing public photos from gumption. Make your own badge here.

Disqus - Latest Comments by gumption

World Wine Weblog