On Wed, 31 Mar 2010 01:27:43 am Damon Timm wrote: [...] > My initial questions are: > > 1. Is there a better way to implement a --quiet flag?
I usually create a function "print_" or "pr", something like this: def print_(obj, verbosity=1): if verbosity > 0: print obj and then have a variable "verbosity" which defaults to 1 and is set to 0 if the user passes the --quiet flag. Then in my code, I write: print_("this is a message", verbosity) > 2. I am not very clear on the use of Exceptions (or even if I am > using it in a good way here) — is what I have done the right > approach? Hmmm... perhaps. Usually, you want to catch an exception in order to try an alternative approach, e.g.: try: result = somefunction(x) except ValueError: # Fall back on some other approach. result = "something else" Occasionally, you want to catch an exception just to ignore it. It's generally *not* a good idea to catch an exception just to print an error message and then exit, as you do. Just let the exception propagate, and Python will print a rich and detailed traceback together with your error message. However, a reasonable exception (pun intended) for that rule is to hide the traceback from the users, who probably can't do anything about it, and would only get confused by the details. So you want to have your functions and classes raise exceptions, and the application layer (the user interface) catch them. So I would do something like this (untested). In your function code: ... if os.path.exists(tar_name): msg = "A tar file already exists this this directory name." \ " Move or rename it and try again." raise DestinationTarFileExists(msg) Then your application layer looks something like: if __name__ == '__main__': try: ... except KeyboardInterrupt: sys.exit(1) except DestinationTarFileExists, e: print e.message sys.exit(2) # Any other exception is unexpected, so we allow Python # to print the full traceback as normal. > 3. Finally, in general: any feedback on how to improve > this? (I am thinking, just now, that the script is only suitable for > a command line usage, and couldn’t be imported by another script, for > example.) Separate the underlying functionality from the application-level code. These functions should NEVER print anything: they do all communication through call-backs, or by returning a value, or raising an exception. E.g.: def tar_bzip2_directories(directories, callback=None): for directory in directories: file_name = '-'.join(directory.split(' ')) tar_name = file_name.replace('/','').lower() + ".tar.bz2" if os.path.exists(tar_name): raise DestinationTarFileExists(errmsg) if callback is not None: callback(directory, filename, tarname) ... Create a main function that runs your application: def main(argv=None, callback=None): if argv is None: argv = sys.argv process_command_line_options(argv) if callback is None: def callback(dirname, filename, tarname): print "Processing ..." tar_bzip2_directories(...) if __name__ == '__main__': try: main() except ... # as above Now anyone can import the module and call individual functions, or even call main, or they can run it as a script. Hope this helps, -- Steven D'Aprano _______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor