Paulo da Silva said:
I got it to work! Is there a better way?
Yup. If you're using Python 2.3, then check out the optparse module, if an
older vesion, getopt.
I didn't like getopt that well, so slapped together something that allowed
me to access options in a script like this:
from options import opts,env,anyopt,params
if opt.verbose:
print 'starting'
if opt.logfile:
logfilename = opt.logfile
debug = anyopt.debug
if debug:
print 'Running under %s's account...' % env.username
for param in params:
dostuff(param)
# ... etc.
If an option was specified on the command line as "/o" then opt.o will be
True. If an option was specified as "/log:test.log" then opt.log will be
"test.log". env gives the same shortcut for environment variables and
anyopt gives a combo of the two (so if you specify /debug, or set the debug
environment variable it is turned on). params are what remain on the
command line after removing argv[0] and all items prefixed with '/' or '-'.
The idea was to get consistent command line handling that was very quick and
easy to use. I still like this for quick and simple scripts. The
weakness is that it is more dynamic, so it doesn't do nifty things like
optparse, where it automatically displays command line syntax.
- Matt
FYI, below is my options.py, but you should probably learn the optparse
module, if you're on Python 2.3:
"""
Three handy instances options classes are contained herein:
1) opts - Command line options.
2) env - Environment 'options'.
3) anyopt - Either command line or environment options (command line
options).
4) params - List of non-option command line paramters.
"""
import os,sys
from glob import glob
# These are the non-option parameters (like filenames, etc.):
params = filter(lambda a:a[0] not in '-/', sys.argv[1:])
#---------------------------------------------------------------------
# FindCommandLineOption()
#
#---------------------------------------------------------------------
def FindCommandLineOption( opt, caseSensitive = 0 ):
"""Finds simple (/s) and parameterized (/f:file.ext) options.
Returns 1 if a simple option is found, returns the
value of an option that specifies on (eg. /f:filename.ext returns
filename.ext'. If None is specified, it returns 1 if no parameters
were specified."""
result = 0
import sys
import string
if caseSensitive:
case = lambda s: s
else:
case = string.lower
if opt == None: # Special case for None; if none, then we want to
if len(sys.argv) == 1: # check whether there were no parameters.
result = 1
else:
for i in sys.argv[1:]:
if i[0] == '-' or i[0] == '/':
curOpt = i[1:]
if case(opt) == case(curOpt):
result = 1
elif ':' in curOpt:
parts = string.split(curOpt,':')
if case(opt) == case(parts[0]):
result = string.join(parts[1:],':') # put together the
rest of the parts
return result
class CommandLineOptions(object):
"""Like the EnvironmentVariables object, this object gives you a clean
and simple interface to the command line options.
Here is how you would check for the /v (or -v) option on the
command line:
opts = CommandLineOptions()
if opts.v:
print 'You chose the verbose option!'
And here is how you would get a file specified by /f:filename:
if opts.f:
if os.path.isfile(opts.f):
filename = opts.f
else:
print "Who you kiddin'? %s is not a valid file!" % opts.f
"""
def __getattr__(self, name):
if name == 'help' and FindCommandLineOption('?'):
return FindCommandLineOption('?')
return FindCommandLineOption(name)
def __getitem__(self,name):
return self.__getattr__(name)
opts = CommandLineOptions()
#---------------------------------------------------------------------
# EnvironmentVariables
#
# Need to either inject them into the current scope, or create an object
# which has a member for each var. I like the latter, as it is cleaner,
# and will avoid hosing locals by using its own namespace.
#---------------------------------------------------------------------
class EnvironmentVariables(object):
def x__init__(self):
import os
import string
for x in os.environ.keys():
name = string.lower( string.join(string.split(x)) )
exec( "self." + name + "='" + os.environ[x] + "'" )
def __getattr__(self, name):
if os.environ.has_key(name):
return os.environ[name]
else:
name = name.replace('_',' ')
return os.environ.get(name,'')
def __getitem__( self, key ):
return os.environ.get(key,'')
env = EnvironmentVariables()
#---------------------------------------------------------------------
# AnyOption
#
# Culls options from the command line and the environment variables.
#---------------------------------------------------------------------
class AnyOption(object):
def __getattr__(self, name):
result = opts.__getattr__(name)
if not result: result = env.__getattr__(name)
return result
def __getitem__( self, key ):
'Allows dictionary syntax'
result = opts[key]
if not result: result = env[key]
return result
anyopt = AnyOption()
#--------------------------------------------------------------------------
# ArgFiles()
#
# Gets all the files specified on the command line, via wildcards. Also
# looks for the /r or /s option, then does a recursive collecting of them.
#
# It would be a little cleaner if this were a variable, like the others,
# instead of a function, but the possibility of a mosterous task resulting
# from an innocent command line (eg. "MyProg c:\\*.*' /s") precludes that.
# So, this is a generator, allowing the caller not to get stuck in a
# long-waiting no-status display situation.
#--------------------------------------------------------------------------
def ArgFiles(args=None):
files = []
if args == None: args = params
for filespec in args:
if filespec[0] == '/': continue
if opts.r or opts.s:
startdir,spec = os.path.split(filespec)
for d,subdir,files in os.walk(startdir):
for f in glob( os.path.join( d, spec ) ):
yield f
else:
for f in glob(filespec):
yield f