0

I'm trying to parse the arguments passed to a script and execute functionality on the fly

#!/usr/bin/python

import sys
from argparse import ArgumentParser


def method_a(sometext):
    print 'a -- {0}'.format(sometext)


def method_b(sometext):
    print 'b -- {0}'.format(sometext)


parser = ArgumentParser(description='A or B')
parser.add_argument('--sometext',
                    dest='sometext',
                    required=False,
                    default=None)

option_group = parser.add_mutually_exclusive_group(required=True)
option_group.add_argument('-a',
                          dest='cmd',
                          action='store_const',
                          const=lambda: method_user(parser.sometext))

option_group.add_argument('--list',
                          '-l',
                          dest='cmd',
                          action='store_const',
                          const=lambda: method_list(parser.sometext))

args = parser.parse_args(sys.argv[1:])
args.cmd()

This unforunately throws the exception:

Traceback (most recent call last):
  File "test.py", line 39, in <module>
    args.cmd()
  File "test.py", line 34, in <lambda>
    const=lambda: method_list(parser.sometext),
AttributeError: 'ArgumentParser' object has no attribute 'sometext'

Is it possible to access the value passed to sometext while parsing later arguments? I'd like to pass the value captured in sometext to the methods being run inside the const field for the mutually exclusive group.

As a side question: is the keyword lambda required in the above example? Or will it execute the method regardless.. I'd use the lambda in a similar example below, but again, is this even required?

switch = {0: lambda: sys.exit(),
          1: lambda: method_a('sometext'),
          2: lambda: method_b('sometext')}
index = int(raw_input('Make a selection'))
switch.get(index)()
1
  • You say "access the value passed to sometext while parsing later arguments", but the way you've set things up, there's no requirement that the other options actually come later. Commented May 27, 2016 at 16:17

1 Answer 1

1

The parser instance itself doesn't hold the parsed arguments, as it is a description of what the expected arguments are and how to parse them. The return value from calling parse_args holds them. A quick way to get what you want would be:

...
option_group.add_argument('-a',
                      dest='cmd',
                      action='store_const',
                      const=lambda args: method_user(args.sometext))

option_group.add_argument('--list',
                      '-l',
                      dest='cmd',
                      action='store_const',
                      const=lambda args: method_list(args.sometext))
args = parser.parse_args()
args.cmd(args)

Ultimately, you could write your own subclasses of the argparse module that would grant you access to the parsed arguments, but I don't recommend that approach because:

  • It's a lot of work and would require subclassing private classes, which is never a good idea.
  • It would need to take into account the ordering of the arguments, which you can't rely on, being a user input.

To answer your side question, you could refer to the function itself, without having to use a lamdba declaration, such as:

...
option_group.add_argument('-a',
                      dest='cmd',
                      action='store_const',
                      const=method_user

option_group.add_argument('--list',
                      '-l',
                      dest='cmd',
                      action='store_const',
                      const=method_list
args = parser.parse_args()
args.cmd(args.sometext)

If you need to refer to a function to be invoked with some parameters, but don't want to wrap it in a lambda, you can use the partial wrapper from the functools module.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.