if (__name__ == '__main__'): main(sys.argv[1:])
François Pinard
pinard at iro.umontreal.ca
Wed Apr 21 08:37:31 EDT 2004
[Erik Heneryd]
> Eli Stevens (WG.c) wrote:
> >I have a question about proper Python style when it comes to having a main
> >function in a module.
> http://www.artima.com/weblogs/viewpost.jsp?thread=4829
I asked myself the same question for a good while, and came up with the
following skeleton from nearly all my Python programs. At times, I
was removing lines below which appeared superfluous to me for smallish
scripts, but found out in the long run that, sooner or later for any
script which was surviving for some while, I have to add back the lines
I removed, while adding new features as needed in such scripts, so I now
stick to that skeleton. More comments follow below.
---------------------------------------------------------------------->
#!/usr/bin/env python
# -*- coding: Latin-1
# Copyright © 2004 Progiciels Bourbeau-Pinard inc.
# François Pinard <pinard at iro.umontreal.ca>, 2004.
"""\
"""
__metaclass__ = type
class Main:
def __init__(self):
pass
def main(self, *arguments):
import getopt
options, arguments = getopt.getopt(arguments, '')
for option, valeur in options:
pass
run = Main()
main = run.main
if __name__ == '__main__':
import sys
main(*sys.argv[1:])
----------------------------------------------------------------------<
If that file is imported instead of executed as a main program, the
`Main.main' method does not execute, but the `Main' object is still
instantiated and available within the imported module under the name
`run'. This can be used to call its methods, modify its options, etc.
The role of `__init__' is to setup the `run' object, and in particular,
to initialise default values for run options. The `main' method proper
goes after the `pass' at its end, which gets replaced, of course, by
option processing if any.
The strange `*' which appears in two place is so that `main' may
be called after the module being imported, with a variable number
of explicit arguments. This has proven to be the most natural and
convenient way to proceed: we think of the `main' method as accepting
a list of arguments, not a bundle them in a list or tuple. This is
useful, in particular, in an interactive Python session. The program
name is not a useful first argument in the general case, this is why it
is excluded in the last line of the above template, when the module is
run as a script.
Of course, the initial doc string is meant to be filled appropriately.
A word about the `__metaclass__' line. My intent is to forget all about
classic classes and go with the new type system as quickly as possible.
I do not want to derive each and every of my classes from `object',
and later edit all those `(object)' out when the classic classes will
effectively get deprecated. Much easier and cleaner to remove that
`__metaclass__' line then. Moreover, by using this `__metaclass__' line
in all my things, I do not risk obscure bugs because I forgot one of
these `object' derivation while I used more recent Python features.
Finally, to criticise myself, I'm not satisfied with the copyright line,
as it does not really state the copyright terms and conditions. I'm
used to include that copyright in all my things, or almost, but I should
either retract the line, or state conditions, for it to be meaningful.
Currently, people sometimes write to me to clarify conditions -- which
are GPL usually, yet my real intent in such things is to favour freedom
for both programming and programmers, much more than spousing FSF
politics which do not address both with equal attention! :-)
--
François Pinard http://www.iro.umontreal.ca/~pinard
More information about the Python-list
mailing list