Path: csiph.com!usenet.pasdenom.info!aioe.org!news.stack.nl!newsfeed.xs4all.nl!newsfeed2.news.xs4all.nl!xs4all!newsgate.cistron.nl!newsgate.news.xs4all.nl!post.news.xs4all.nl!not-for-mail Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.000 X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; 'scripts': 0.03; 'interfaces': 0.04; 'receives': 0.04; 'value,': 0.04; 'argument': 0.05; 'none:': 0.07; 'sys': 0.07; '"__main__":': 0.09; '__name__': 0.09; 'arguments': 0.09; 'below)': 0.09; 'exit': 0.09; 'function,': 0.09; 'main()': 0.09; 'parameter': 0.09; 'received:80.91': 0.09; 'received:80.91.229': 0.09; 'received:gmane.org': 0.09; 'received:list': 0.09; 'subject:using': 0.09; 'try:': 0.09; 'python': 0.11; 'def': 0.12; '(via': 0.16; 'arg': 0.16; 'finney': 0.16; "function's": 0.16; 'function;': 0.16; 'main().': 0.16; 'main():': 0.16; 'received:80.91.229.3': 0.16; 'received:plane.gmane.org': 0.16; 'systemexit': 0.16; 'subject:python': 0.16; 'code.': 0.18; 'implementing': 0.19; 'small,': 0.19; 'command': 0.22; 'import': 0.22; 'print': 0.22; 'header:User-Agent:1': 0.23; 'config': 0.24; 'script': 0.25; '(see': 0.26; 'changes,': 0.26; 'specially': 0.26; 'header:X-Complaints-To:1': 0.27; 'function': 0.29; 'raise': 0.29; 'needed.': 0.30; 'program,': 0.31; 'code': 0.31; 'easier': 0.31; 'writes:': 0.31; 'allows': 0.31; 'run': 0.32; 'skip:# 10': 0.33; 'except': 0.35; 'but': 0.35; 'subject:?': 0.36; 'list': 0.37; 'easily': 0.37; 'being': 0.38; 'ben': 0.38; 'to:addr:python-list': 0.38; 'itself': 0.39; 'to:addr:python.org': 0.39; 'skip:p 20': 0.39; 'received:org': 0.40; 'called': 0.40; 'catch': 0.60; 'units': 0.60; 'further': 0.61; "you'll": 0.62; 'needing': 0.65; 'skip:\xe2 10': 0.65; '8bit%:40': 0.68; 'design.': 0.68; 'subject:there': 0.68; '8bit%:43': 0.74; '\xe2\x80\x93': 0.77; 'belief': 0.84; 'difference.': 0.84; 'speaks': 0.91 X-Injected-Via-Gmane: http://gmane.org/ To: python-list@python.org From: Ben Finney Subject: Re: Is there any advantage to using a main() in python scripts? Date: Wed, 11 Dec 2013 21:26:35 +1100 References: <32615c9a-b983-4399-bb55-6df6c230f247@googlegroups.com> Mime-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Gmane-NNTP-Posting-Host: rasputin.madmonks.org X-Public-Key-ID: 0xAC128405 X-Public-Key-Fingerprint: 517C F14B B2F3 98B0 CB35 4855 B8B2 4C06 AC12 8405 X-Public-Key-URL: http://www.benfinney.id.au/contact/bfinney-gpg.asc X-Post-From: Ben Finney User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.4 (gnu/linux) Cancel-Lock: sha1:Wm9H4opjOhJv5gRaIuV4iAFzW20= X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Newsgroups: comp.lang.python Message-ID: Lines: 66 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1386757610 news.xs4all.nl 2964 [2001:888:2000:d::a6]:35201 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:61544 JL writes: > Python scripts can run without a main(). What is the advantage to > using a main()? Modular code – that is, implementing the program functionality in small, well-defined units with narrow, strictly-defined interfaces – is good design. Practical benefits include being able to easily use the code as part of a larger program, and being able to easily unit-test all the program's code. > Is it necessary to use a main() when the script uses command line > arguments? (See script below) > > #!/usr/bin/python > > import sys > > def main(): > # print command line arguments > for arg in sys.argv[1:]: > print arg > > if __name__ == "__main__": > main() Better design is to make the argument list a parameter to the ‘main’ function; this allows constructing an argument list specially for calling that function, without ‘main’ needing to know the difference. You'll also want to catch SystemExit and return that as the ‘main’ function's return value, to make it easier to use as a function when that's needed. def main(argv=None): if argv is None: argv = sys.argv exit_code = 0 try: command_name = argv[0] config = parse_command_args(argv[1:]) do_whatever_this_program_does(config) except SystemExit, exc: exit_code = exc.code return exit_code if __name__ == "__main__": import sys exit_code = main(sys.argv) sys.exit(exit_code) That way, the normal behaviour is to use the ‘sys.argv’ list and to raise SystemExit (via ‘sys.exit’) to exit the program. But ‘main’ itself can, without any further changes, be called as a function that receives the command line as a parameter, and returns the exit code. -- \ “Faith, n. Belief without evidence in what is told by one who | `\ speaks without knowledge, of things without parallel.” —Ambrose | _o__) Bierce, _The Devil's Dictionary_, 1906 | Ben Finney