2
\$\begingroup\$

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.

Example:

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 ...

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.-----------
\$\endgroup\$

4 Answers 4

4
\$\begingroup\$

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:])
\$\endgroup\$
2
\$\begingroup\$

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().

\$\endgroup\$
0
\$\begingroup\$

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

\$\endgroup\$
2
  • 1
    \$\begingroup\$ optparse seems to be deprecated since version 2.7 \$\endgroup\$
    – Kinjal
    Dec 18, 2012 at 10:19
  • 1
    \$\begingroup\$ @Kinjal You are right. But there is argparse which has a similar syntax. \$\endgroup\$ Dec 18, 2012 at 10:42
0
\$\begingroup\$

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.

\$\endgroup\$

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