Sherry
Sherry

Reputation: 331

Calling a function using argparse

I am trying to call the function addPXT through argparse when type -a. Its not doing that. Read another issue, there addPXT was not in colons, tried that it says addPXT is not callable.

parser = argparse.ArgumentParser()
parser.add_argument('-a' ,action='store_const'  ,const='addPXT')
results = parser.parse_args()

def addPXT():
        print "hello"

    python script.py -a

Upvotes: 0

Views: 15577

Answers (3)

tdelaney
tdelaney

Reputation: 77347

argparse will call the action object during parsing but you need to supply something that looks like the Action class because the parser will use that object later. The Action doc says

You may also specify an arbitrary action by passing an Action subclass or other object that implements the same interface. The recommended way to do this is to extend Action, overriding the call method and optionally the init method.

So, create an Action subclass and have it call your function

import argparse
import sys

def addPXT():
    print "hello"

class FooAction(argparse.Action):
    def __call__(self, parser, namespace, values, option_string=None):
        addPXT()

parser = argparse.ArgumentParser()
parser.add_argument('-a', action=FooAction)
results = parser.parse_args(sys.argv[1:])

Upvotes: 3

hpaulj
hpaulj

Reputation: 231385

If you are a beginner with argparse and python, I'd recommend sticking with the default store action, which stores strings, and the boolean actions ('store_true/false'). Make sure you understand those first.

That said, here is a way of using store_const to call different functions:

In [131]: import argparse

define 2 functions:

In [132]: def act1():
     ...:     print('act1')
     ...:    
In [133]: def act2():
     ...:     print('act2')
     ...:     
In [134]: parser=argparse.ArgumentParser()
In [135]: parser.add_argument('-a',action='store_const',default=act1,const=act2);

I define both the default and the const - and specify the functions, not their names. Understanding the difference is important.

Try the default case:

In [136]: args=parser.parse_args([])
In [137]: print(args)
Namespace(a=<function act1 at 0xb07331dc>)
In [138]: args.a()
act1

Try the -a commandline case:

In [139]: args=parser.parse_args(['-a'])
In [140]: print(args)
Namespace(a=<function act2 at 0xb078c1dc>)
In [141]: args.a()
act2

If you have more arguments (dest), you could pass args to your function, if it is defined to accept them, args.a(args).

The simpler boolean argument approach:

In [146]: parser=argparse.ArgumentParser()
In [147]: parser.add_argument('-a',action='store_true');
In [148]: args=parser.parse_args([])
In [149]: print(args)
Namespace(a=False)
In [150]: if args.a:
     ...:     act2()
     ...: else:
     ...:     act1()
act1
# similarly for `['-a']`.

or if you accept strings, maybe even choices

if args.a == 'act1':
     act1()
elif ...

The primary purpose of argparse is to deduce what the user wants, and issue help and error messages. Acting on that information is largely the responsibility of the rest your code.

Upvotes: 7

ODiogoSilva
ODiogoSilva

Reputation: 2414

You're missing a destoption in the add_argument to be able to reference the option.

You will then need to test if the -a option was passed as argument. If so, then call the function.

parser = argparse.ArgumentParser()
parser.add_argument('-a' ,dest="my_flag", action='store_const'  ,const=True)
results = parser.parse_args()

def addPXT():
    print "hello"

if results.my_flag:
    addPXT()

Upvotes: 0

Related Questions