Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #61541 > unrolled thread
| Started by | JL <lightaiyee@gmail.com> |
|---|---|
| First post | 2013-12-11 01:55 -0800 |
| Last post | 2013-12-11 16:22 -0500 |
| Articles | 10 — 8 participants |
Back to article view | Back to comp.lang.python
Is there any advantage to using a main() in python scripts? JL <lightaiyee@gmail.com> - 2013-12-11 01:55 -0800
Re: Is there any advantage to using a main() in python scripts? Ben Finney <ben+python@benfinney.id.au> - 2013-12-11 21:26 +1100
Re: Is there any advantage to using a main() in python scripts? Chris Angelico <rosuav@gmail.com> - 2013-12-11 21:41 +1100
Re: Is there any advantage to using a main() in python scripts? marduk@letterboxes.org - 2013-12-11 07:57 -0500
Re: Is there any advantage to using a main() in python scripts? Roy Smith <roy@panix.com> - 2013-12-11 09:20 -0500
Re: Is there any advantage to using a main() in python scripts? Roy Smith <roy@panix.com> - 2013-12-11 09:17 -0500
Re: Is there any advantage to using a main() in python scripts? rusi <rustompmody@gmail.com> - 2013-12-11 06:24 -0800
Re: Is there any advantage to using a main() in python scripts? bob gailer <bgailer@gmail.com> - 2013-12-11 10:42 -0500
Re: Is there any advantage to using a main() in python scripts? Chris Angelico <rosuav@gmail.com> - 2013-12-12 02:49 +1100
Re: Is there any advantage to using a main() in python scripts? Terry Reedy <tjreedy@udel.edu> - 2013-12-11 16:22 -0500
| From | JL <lightaiyee@gmail.com> |
|---|---|
| Date | 2013-12-11 01:55 -0800 |
| Subject | Is there any advantage to using a main() in python scripts? |
| Message-ID | <32615c9a-b983-4399-bb55-6df6c230f247@googlegroups.com> |
Python scripts can run without a main(). What is the advantage to using a main()? 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()
[toc] | [next] | [standalone]
| From | Ben Finney <ben+python@benfinney.id.au> |
|---|---|
| Date | 2013-12-11 21:26 +1100 |
| Message-ID | <mailman.3880.1386757610.18130.python-list@python.org> |
| In reply to | #61541 |
JL <lightaiyee@gmail.com> 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
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2013-12-11 21:41 +1100 |
| Message-ID | <mailman.3881.1386758510.18130.python-list@python.org> |
| In reply to | #61541 |
On Wed, Dec 11, 2013 at 9:26 PM, Ben Finney <ben+python@benfinney.id.au> wrote: > except SystemExit, exc: For new code, you'd of course want to write that as: except SystemExit as exc: which is compatible with Python 2.6, 2.7, and 3.x, while the other syntax is 2.x only. ChrisA
[toc] | [prev] | [next] | [standalone]
| From | marduk@letterboxes.org |
|---|---|
| Date | 2013-12-11 07:57 -0500 |
| Message-ID | <mailman.3895.1386766655.18130.python-list@python.org> |
| In reply to | #61541 |
I would agree with the previous post but also add that I've stopped calling the main function "main()" and usually give it a more descriptive name, such as "bake_cookies()" or whatever. I think that that makes it clearer what it's doing when used as a library and the 'if __name__ == '__main__'" already implies that it is the "main" script function.
[toc] | [prev] | [next] | [standalone]
| From | Roy Smith <roy@panix.com> |
|---|---|
| Date | 2013-12-11 09:20 -0500 |
| Message-ID | <roy-E30525.09202911122013@news.panix.com> |
| In reply to | #61564 |
In article <mailman.3895.1386766655.18130.python-list@python.org>, marduk@letterboxes.org wrote: > I would agree with the previous post but also add that I've stopped > calling the main function "main()" and usually give it a more > descriptive name, such as "bake_cookies()" or whatever. I think that > that makes it clearer what it's doing when used as a library and the 'if > __name__ == '__main__'" already implies that it is the "main" script > function. If you're writing a library that's meant to be imported by other scripts, then that makes sense. I tend to use main() for things that are done when your script is run as a stand-alone program. That usually involves things like parsing command-line arguments, and configuring logging, neither of which you'd want to do in an importable library.
[toc] | [prev] | [next] | [standalone]
| From | Roy Smith <roy@panix.com> |
|---|---|
| Date | 2013-12-11 09:17 -0500 |
| Message-ID | <roy-6DF7ED.09173411122013@news.panix.com> |
| In reply to | #61541 |
In article <32615c9a-b983-4399-bb55-6df6c230f247@googlegroups.com>, JL <lightaiyee@gmail.com> wrote: > Python scripts can run without a main(). What is the advantage to using a > main()? 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() No, it's not necessary, but it's a good idea. For one thing, it lets you import your script without actually running it. We recently tracked down a long-standing bug where some maintenance script we had started out with: import os os.environ['DJANGO_SETTINGS_MODULE'] = 'whatever' somebody imported that script in another part of the system because there was some convenient definition that he wanted to reuse. Unfortunately, the act of importing the script changed the environment! The fix was to move the setting of the environment variable to inside the main() routine. If you always follow the rule that you always put all your executable code inside main(), you'll never run into problems like that.
[toc] | [prev] | [next] | [standalone]
| From | rusi <rustompmody@gmail.com> |
|---|---|
| Date | 2013-12-11 06:24 -0800 |
| Message-ID | <b028423f-42e3-40ed-8140-9515e2700267@googlegroups.com> |
| In reply to | #61574 |
On Wednesday, December 11, 2013 7:47:34 PM UTC+5:30, Roy Smith wrote: > JL wrote: > > Python scripts can run without a main(). What is the advantage to using a > > main()? 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() > No, it's not necessary, but it's a good idea. > For one thing, it lets you import your script without actually running > it. We recently tracked down a long-standing bug where some maintenance > script we had started out with: > import os > os.environ['DJANGO_SETTINGS_MODULE'] = 'whatever' > somebody imported that script in another part of the system because > there was some convenient definition that he wanted to reuse. > Unfortunately, the act of importing the script changed the environment! > The fix was to move the setting of the environment variable to inside > the main() routine. If you always follow the rule that you always put > all your executable code inside main(), you'll never run into problems > like that. I guess these are important but somewhat advanced considerations. For a beginner, its important to get that there is a bit of a pun here: The function habitually called 'main' may be called that or anything else It can have or not have an argument as Ben pointed out -- maybe more than one also. The module name __main__ is however sacrosanct and hardwired into python. The habit of connecting the one with the other is partly conventional and partly unavoidable
[toc] | [prev] | [next] | [standalone]
| From | bob gailer <bgailer@gmail.com> |
|---|---|
| Date | 2013-12-11 10:42 -0500 |
| Message-ID | <mailman.3904.1386776551.18130.python-list@python.org> |
| In reply to | #61541 |
On 12/11/2013 4:55 AM, JL wrote: > What is the advantage to using a main()? In addition to what's been said I add: It separates all the global activities: defining of functions and classes, importing modules, etc. from the "doing" the actual task of the program. It also ensures that the defining all the classes and functions happens before referencing them (less "bookkeeping" for me). These two allow me to write the main program first, and follow it with all the global stuff.
[toc] | [prev] | [next] | [standalone]
| From | Chris Angelico <rosuav@gmail.com> |
|---|---|
| Date | 2013-12-12 02:49 +1100 |
| Message-ID | <mailman.3906.1386776974.18130.python-list@python.org> |
| In reply to | #61541 |
On Thu, Dec 12, 2013 at 2:42 AM, bob gailer <bgailer@gmail.com> wrote: > It also ensures that the defining all the classes and functions happens > before referencing them (less "bookkeeping" for me). > > These two allow me to write the main program first, and follow it with all > the global stuff. I prefer define-before-use for readability, even if it doesn't matter to the language. It means that locating the source of something can be found by going upward (or starting at the top and going down - first hit should be the definition), and helps keep things organized. Obviously it's not always possible (mutual recursion, for instance), but it's a general rule of thumb that I like to maintain. ChrisA
[toc] | [prev] | [next] | [standalone]
| From | Terry Reedy <tjreedy@udel.edu> |
|---|---|
| Date | 2013-12-11 16:22 -0500 |
| Message-ID | <mailman.3934.1386796935.18130.python-list@python.org> |
| In reply to | #61541 |
On 12/11/2013 5:26 AM, Ben Finney wrote: > 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. In particular, it is easier to write tests when argv is a parameter. -- Terry Jan Reedy
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.python
csiph-web