views:

1741

answers:

8

Many python IDE's will start you with a template like:

print 'hello world'

That's not enough... So here's my skeleton code to get this question started:

My Module Skeleton, Short Version:

#!/usr/bin/env python

"""
Module Docstring
"""

#
## Code goes here.
#

def test():
    """Testing Docstring"""
    pass

if __name__=='__main__':
    test()

and,

My Module Skeleton, Long Version:

#!/usr/bin/env python
# -*- coding: ascii -*-

"""
Module Docstring
Docstrings: http://www.python.org/dev/peps/pep-0257/
"""

__author__ = 'Joe Author ([email protected])'
__copyright__ = 'Copyright (c) 2009-2010 Joe Author'
__license__ = 'New-style BSD'
__vcs_id__ = '$Id$'
__version__ = '1.2.3' #Versioning: http://www.python.org/dev/peps/pep-0386/

#
## Code goes here.
#

def test():
    """ Testing Docstring"""
    pass

if __name__=='__main__':
    test()

Notes (PEP 8, UTF-8):

"""
===MODULE TYPE===
Since the vast majority of my modules are "library" types, I have constructed
this example skeleton as such. For modules that act as the main entry for
running the full application, you would make changes such as running a main()
function instead of the test() function in __main__.

===VERSIONING===
The following practice, specified in PEP 8, no longer makes sense:

   __version__ = '$Revision: 1.2.3 $'

For two reasons:
    (1) Distributed version control systems make it neccessary to include more
        than just a revision number. E.g. author name and revision number.
    (2) It's a revision number not a version number.


Instead, the __vcs_id__ variable is being adopted. This expands to, for
example:
    __vcs_id__ = '$Id: example.py,v 1.1.1.1 2001/07/21 22:14:04 goodger Exp $'


===VCS DATE===
Likewise, the date variable has been removed:

    __date__ = '$Date: 2009/01/02 20:19:18 $'


===CHARACTER ENCODING===
If the coding is explicitly specified, then it should be set to the default
setting of ASCII. This can be modified if necessary (rarely in practice).
Defaulting to UTF-8 can cause anomalies with editors that have poor unicode
support.

"""

Alternate Skeleton, Long Version:

(Code adapted from DasIch's answer.)

#!/usr/bin/env python
# -*- coding: ascii -*-

"""
package.module
~~~~~~~~~~~~~

A description which can be long and explain the complete
functionality of this module even with indented code examples.
Class/Function however should not be documented here.

:copyright: year by my name, see AUTHORS for more details
:license: license_name, see LICENSE for more details
"""

#
## Code goes here.
#

def test():
    """ """
    pass

if __name__=='__main__':
    test()

There are a lot of PEPs that put forward coding style recommendations. Am I missing any important best practices? What is the best Python module skeleton code?

Update

Show me any kind of "best" that you prefer. Tell us what metrics you used to qualify "best".

+1  A: 

Depending on the nature of the program, you could consider choosing a license and putting it at the start of the file.

Francesco
+9  A: 

It is often advisable to set

#coding=<coding>

at the second line. Like

#coding=utf8

For example. This an alternative to the verbose

# -*- coding: <encoding name> -*-

See PEP-263 for more info.


Edit for full answer: Depends on the situation. If its for some internal project, simpler is better. But I almost always have

def main():
    #code
    pass

if __name__=="__main__":
    main()

If I intend to publish the code, I add proper documentation and licensing terms as well as the mentioned encoding directive.

The shebang (#!/usr/bin/env python) is only necessary for the file that is meant to be the executable.

Otto Allmendinger
it is utf-8 with a dash, IIRC (+1 from me :-) )
Francesco
@Francesco: looks like utf8 is a valid alias: http://docs.python.org/library/codecs.html - python throws an error if you set an invalid encoding
Otto Allmendinger
@Otto: thanks, I forgot it.
Francesco
Use UTF-8 with dash (or utf-8). Some tools (intltool) refuse files with a utf8 declaration.
kaizer.se
Sometimes useful, but generally not important. Most coding standards force ASCII and python warns you loudly if you otherwise deviate from this without the declaration.
I'd use variant with -*- just because it's Emacs' file variables syntax.
piranha
+2  A: 

Returning something is a best practice too (here with called args):

...
import sys

def main(args):
    return 0

if __name__=='__main__':
    sys.exit(main(sys.argv))

But it's becoming more complex than a simple "hello world".

manatlan
That is an interesting perspective.
+6  A: 

Even better, here is the suggested package layout by Dr. Titus Brown:

http://github.com/ctb/SomePackage

fuzzyman
Yes, after modules, there's whole packages. Good starting reference for packages.
A: 

How about:

...
import sys

def main(*args):
    return 0

if __name__=='__main__':
    sys.exit(main(*sys.argv[1:]))

Then of course you modify that skeleton main to reflect actual parameters of the program (after the filename):

def main(arg1, arg2, *args):
    ...

(Surprised we can't use Markdown in comments...)

L33tminion
To people still using sys.argv directly, have you heard of http://code.google.com/p/pyopt/ ?
It's not always sensible to add further dependencies just for example code (which is what main functions will usually be used for in proper modules).
Alan
> (Surprised we can't use Markdown in comments...)*Some* Markdown works in comments, but not enough in my book.
Paul D. Waite
@user213060 `pyopt` looks suitable for one-offs, but `optparse` works wonderfully and is in the standard library, and doesn't require all that much more hand-wiring.
gotgenes
+2  A: 

I would say the best is the simplest one than satisfies your requirements. The more data you put to the 'skeleton' the more outdated or meaningless or mistaken data you may get there.

  • The if __name__=='__main__': part is not needed in a module that is just a module. Tests may be part of the module, but even then they could be called externally. Calling a module directly is often plain inconvenient (or impossible, e.g. when relative imports are used).
  • Python interpreter will usually say when the coding information is needed, not every piece code needs non-ascii characters.

The reasonable minimum IMHO is the docstring at the beginning of the module. Other pieces, mentioned in your question and other answers are also often useful, but are in no way obligatory.

Jacek Konieczny
I agree that defaulting to utf-8 is a poor choice. I disagree for the testing. I think it's great require the inclusion of testing, or at least have a stub for it, right there in the module for first versions. Then, the testing can be moved to an outside module as the module matures. Overall, appreciate the input.
As for "simplest one that satisfies requirements", I cringe when Windows users omit the `#!/usr/bin/env python` at the beginning. This can lead to the script being run by the bash interpreter by default. Very bad or strange things can happen then...
`#!/usr/bin/python` (I don't like /bin/env version for various reasons, but this is off-topic) is needed for python scripts (executables) not modules. Not every module needs to be an executable.
Jacek Konieczny
“the simplest one than satisfies your requirements” — amen. I can’t think of anything more Pythonic than that.
Paul D. Waite
+4  A: 

Modules aren't executable, so they shouldn't have a shebang.

Docstrings are good.

Coding is useful.

Metadata such as author, copyright, version and license as best stored in the setup.py as part of the packaging metadata. The usage of __(metadata)__ module attributes is an outdated practice, as it predates the time when Python had packaging metadata. If the code is of an ephemeral enough nature not to warrant packaging, then it's unlikley that you're going to need any of the metadata.

Additional features such as test() or a __main__ hack I don't use nearly enough to warrant inclusion in a module template.

So the only template needed is:

# -*- coding: ascii -*-
"""
"""

Nice and simple.

Wheat
Think of a module skeleton template as something that can eliminate the reentry of commonly typed code. If you were to look at the last 100 modules you've written, I'm sure you'd find that this skeleton has fallen well short in this regard.
+3  A: 
#!/usr/bin/env python
# coding: utf-8
"""
    package.module
    ~~~~~~~~~~~~~

    A description which can be long and explain the complete
    functionality of this module even with indented code examples.
    Class/Function however should not be documented here.

    :copyright: year by my name, see AUTHORS for more details
    :license: license_name, see LICENSE for more details
"""

The module may or may not contain a main function so that's not part of the template.

DasIch
Most unique contribution that had usable ideas. Was looking for more unique answers like this. Good job.