0

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
OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
Sherry
  • 311
  • 2
  • 4
  • 9
  • 1
    Why did you think it *would* do that? – jonrsharpe Nov 03 '16 at 18:10
  • I am trying to call a function, read another issue. this was recommended – Sherry Nov 03 '16 at 18:12
  • Could you link to that, and provide an actual [mcve]? By colons do you mean quotes? – jonrsharpe Nov 03 '16 at 18:13
  • *The const argument of add_argument() is used to hold constant values* -- Are you sure that should be the function name? – OneCricketeer Nov 03 '16 at 18:14
  • What is your goal? `argparse` is for parsing command line arguments and not for calling arbitrary functions. If `addPTX` is supposed to process an argument, for later use by your program, then great. But read how the [action](https://docs.python.org/3/library/argparse.html#action) keyword works. It has a specific role and it uses an [Action](https://docs.python.org/3/library/argparse.html#argparse.Action) object. – tdelaney Nov 03 '16 at 18:22
  • I want that when -a passed as a argument it should call the function addPXT(), that function further have variables which I can assign values through the dest value – Sherry Nov 03 '16 at 18:36
  • I am using python 2.7 – Sherry Nov 03 '16 at 18:51

3 Answers3

6

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.

hpaulj
  • 221,503
  • 14
  • 230
  • 353
  • http://stackoverflow.com/questions/19251204/execute-function-via-arg I tried with type also didn't work for me. – Sherry Nov 03 '16 at 21:11
  • Make sure you understand when the `type` function is executed. See my comment on the accepted answer of your link. – hpaulj Nov 03 '16 at 21:19
  • parser.add_argument('-a' ,action='store_const',default='addPXT',const='test'); I tried to use ur method, I am not able to give default and const as function names, its accepting as a string only. when I tries results.a() it says str not callable. On the other hand if i remove colons i get addPXT not defined – Sherry Nov 03 '16 at 21:21
  • `its accepting as a string only` - elaborate. What's the error message? You need to understand the difference between function names (references) and strings. Strings aren't callable. The end of my code shows how string values could be used. – hpaulj Nov 03 '16 at 21:29
  • Traceback (most recent call last): File "PXT.py", line 17, in parser.add_argument('-a' ,action='store_const',default='addPXT',const=test); NameError: name 'test' is not defined – Sherry Nov 03 '16 at 21:32
  • def test(): print "hello" – Sherry Nov 03 '16 at 21:33
  • Define the functions first – hpaulj Nov 03 '16 at 21:50
  • thanks that's working. but I would like to have a one liner – Sherry Nov 03 '16 at 21:59
3

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:])
tdelaney
  • 73,364
  • 6
  • 83
  • 116
0

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()
ODiogoSilva
  • 2,394
  • 1
  • 19
  • 20
  • Whether this is the right answer depends on OP's intent. If OP wants to define an alternate action for the command parser, an `Action` object would be more appropriate. – tdelaney Nov 03 '16 at 18:23
  • Right, but as far as I know the `action` keyword does not support function calling in py3 https://docs.python.org/3/library/argparse.html#action – ODiogoSilva Nov 03 '16 at 18:25
  • Use `action='store_true' to get a simple True/False flag. For a beginner Python/argparse user simple True/False and string arguments are best. – hpaulj Nov 03 '16 at 18:31
  • Without the `dest`, `results.a` fetches the value. Or use `('-a','--my_flag',...)`. – hpaulj Nov 03 '16 at 19:26
  • The `action` keyword expects a `Action`-like object which should do some preprocessing on the option before the parser continues on its way. Depending on what OP wants to do, either your answer or something using an `Action` object is best. – tdelaney Nov 03 '16 at 19:30