Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

I have a python file with several function definitions in it. One of the functions, named 'main' will be called as soon as the python file is run.

ex:   
myFile.py
import sys
def main(arg1....):
  ---code---

--more functions--

main()

When a person wants to run my file they'll type:

python myFile.py arg1 arg2 ...

My question: The main function is supposed to accept in x number of arguments, however, in case the user doesn't wish to pass in any arguments we're supposed to have default values.

my program looks something like this and I'm hoping there is actually a better way to do this than what I have:

myFile.py
import sys
#Even though my function has default values, if the user doesn't wish
#to input in any parameter values, they still must pass in the word False
#otherwise, pls pass in parameter value
def main(name = "Bill", age = 22, num_pets=5, hobby = "soccer"):
   if len(sys) > 1:
      i =0
      while i < len(sys):
         if i == 0:
            if sys.argv[i] == "False":
               i += 1
               continue
            else:
                name = sys.argv[i]
                i += 1
                continue
         elif i == 1:
            if sys.argv[i] == "False":
     --------etc. etc.-----------

Is there a better way to do this?

Thank you in advance

share|improve this question
add comment

4 Answers 4

In case the number of arguments is really long then you can use **kwargs to avoid cluttering up arguments in function definition block. I would also avoid naming the function as "main" and replace it with something like "execute".

def execute(**kwargs):
  name = kwargs.get('name', 'Bill')
  # get other values
  pass

if __name__ = "__main__":
  execute(*sys.argv[1:])
share|improve this answer
add comment

You can use the apply operator (*):

import sys

def main(name = "Bill", age = 22, num_pets=5, hobby = "soccer"):
    pass

if __name__ = "__main__":
    main(*sys.argv[1:])

You can also use argparse to sanitize the contents of sys.argv before applying them to main().

share|improve this answer
add comment

You can also use optparse

Here is an example:

import optparse
...
if __name__ == '__main__':
    parser = optparse.OptionParser()
    parser.add_option('-s', '--string', dest = 'someVar', default = 'default', help = '-s with a small s. With default Value')
    parser.add_option('-S', '--boolean', action = 'store_true', dest = 'someBool', help = 'i am a flag :). Use me with a capital S')

    (options, args) = parser.parse_args()

    main(options)

Then your users have to call it like

python script.py -s HerpDerp

or

python script.py -h

to see a list of available arguments

share|improve this answer
    
optparse seems to be deprecated since version 2.7 –  Kinjal Dec 18 '12 at 10:19
    
@Kinjal You are right. But there is argparse which has a similar syntax. –  user1882585 Dec 18 '12 at 10:42
add comment

I'd suggest using high-level fool-proof libraries like argparse.

The problem with argparse is that its syntax is too verbose, so I developed Argh. It helps maintain the code simple and pythonic:

import argh

def main(name, age=22, num_pets=5, hobby='soccer'):
    yield 'This is {name}, {age}'.format(name=name, age=age)
    yield 'He has ' + ('one pet' if num_pets < 2 else 'many pets')

argh.dispatch_command(main)

Example usage:

$ ./script.py Bill
This is Bill, 22
He has many pets

$ ./script.py John -a 50 --num-pets=1 --hobby sleeping
This is John, 50
He has one pet

This can be easily tuned if you don't mind diving into the documentation.

Of course it's not the only library in this field.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.