Some time ago, I had read an article on Guido's blog (I think) about ways to improve the main() functionin a Python script. There were many replies, and I thought I would try to implement some of these ideas.
I had found that in every python program I wrote I would 1. check the number of arguments as well as checking that each argument was valid. 2. Provide an option for the user to display how long the program took to run, for those programs which
processed a lot of files. 3 If any input files were used, I would also check to make sure they existed. Recently, I've implemented a browser dialogue from Jimmy Retzlaff's EasyDialogs to make it easy to locate
files outside of the current directory.4. If the argument validation failed, a Usage() function would be called to show all possible arguments5. Provide a "help" option to display all the possible arguments.
I could see that I was writing enough lines of code that main() was getting cluttered, and not easy to see what was happening at a glance. Sure, I could move all of this outside of main(), but some function had to
initiate all of the processing. So, I've decided to put all of this processing into a class. I had thought about putting this class in a separate file, so the file containing main() would only have a few imports, one line to instantiate the class to validate the cmd line args, and one function call to actually "start" the meat of the program, if all input args were valid.
I didn't like the idea of having to start with 2 files for every program. So now the class definition for the input processing is in the main file, and this file is now full of code, but at least main() is short & sweet.
Since I'm just getting back into using Python again, I would appreciate some constructive comments on this processing, and if this version of "a better main()" is really better or not.
So Now I'm trying to use more exception handling in the validating of the input arguments, and have defined a few of my own exceptionclasses.However, I'm getting the cart before the horse, and can't see the forest through the trees.
I don't like the idea of defining classes within classes, but I'm havign a problem geting the ProgramStartup class tosee the ArgumentError exception class.Am Ion the right track to makign a better main by moving all the argument validation to a class, or should I levae it to discrete functions in the main file?
thanks# system importsfrom os import getcwdimport stringimport sysimport typesimport timeimport getoptfrom EasyDialogs import AskFileForOpenfrom os.path import existsfrom exceptions import Exception
# system imports# user-defined importsimport tcpyfrom tcpy import pausefrom tcpy import cls# user-defined imports#/# USER-DEFINED EXCEPTIONS
class UserExceptions(Exception): def __init__(self, args=None): self.args = argsclass ArgumentError(UserExceptions): def __init__(self): #UserExceptions.__init__(self, args)
#self.args = args pass class ProgramExitError(UserExceptions): def __init__(self, args): UserExceptions.__init__(self, args) self.args = args
#/# CLASS DEFINITIONS#/class ProgramStartup(object): "this class will handle all the details of checking/validating the program arguments"
def __init__(self, ProgramArgs): self.MinArgs = 1 self.MaxArgs = 2 #input filename self.ShowTimer = False self.StartTime = 0 self.EndTime = 0
self.InputFilename = "" self.ProgramName = "" self.ProgramVersion = "0.1" self.BAD_ARG = True self.ArgsDict ={'-t':"Show program execution time",
'-v':"Show program version number", '-b':"Browse for input file", '-f ':"File to be processed",
'-h':"Show this help screen" } self.ValidArgs ='tvbf:' try: self.ValidateArgs(ProgramArgs) except getopt.GetoptError
, ArgumentError: self.Usage() def Usage(self): print"\nSyntax is: ", print"%s " % ProgramName, for key in self.ArgsDict.iterkeys():
print"%s " % key, print"\n\nWhere" for key, item in self.ArgsDict.iteritems(): print"\n%s=%s" %(key, item) print
sys.exit() def ShowExecTime(self): if self.ShowTimer: print"\nTotal time = %6.2f seconds" % (self.EndTime-self.StartTime) return None
def ShowTitle(self): print"\n\n%s Version %s \n\n" %(self.ProgramName, self.ProgramVersion) return None def ValidateArgs(self, args): global AskFileForOpen, getcwd, ArgumentError
ArgValidationStatus = 0 self.InputFilename = Non