Use optparse to call a function - python

How to call a function using optparse? I do not want to use argparse.
Here is my code:
from optparse import OptionParser
def print_stuff():
a = "Hello Word"
print a
parser = OptionParser()
parser.add_option("-c",
action = "callback",
callback = print_stuff()
)
(options, args) = parser.parse_args()
But it shows me an error:
optparse.OptionError: option -c: callback not callable: None
What to do?
What if I wanted to do:
from optparse import OptionParser
def print_stuff(a):
a = "Hello Word"
return a
parser = OptionParser()
parser.add_option("-c",
action = "callback",
callback = print_stuff()
)
(options, args) = parser.parse_args()

You want
callback = print_stuff
without the parens. Including the parens invokes the function, and sets callback to the result (the string "Hello Word"), which is not callable. Without the parens, you're referring to the function itself.

Related

running python script with argparser

Trying to run my script using argparser, where the program does not run, unless correct argument is in place, however it does not seem to work;
AttributeError: 'Namespace' object has no attribute 'func'
import sys
import argparse
from develop import Autogit as gt
def main():
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers()
# Create argument command
parser_update = subparsers.add_parser('--sync', help='Sync local and remote repos')
parser_update.set_defaults(func=gt.run)
# Adding arguments
parser.add_argument('--sync', type=str, required=True)
if len(sys.argv) <= 1:
sys.argv.append('--help')
options = parser.parse_args()
options.func() # <--- Causes the error
if __name__ == '__main__':
main()
Also when the --sync arg is given it ask for another, then when I add one more argument. SYNC, then it returns attribute error.
Edit
Trying to make the program run the develop.Autogit.run
Working..
Had to also add args as argument in the run funciton i am calling.
I think what you are trying to accomplish is setting a default, typically this is done with ArgumentParser.set_defaults(). You need to do this with the uninitialised function. See this example:
import sys
import argparse
def f(args):
print("In func")
print(args)
def main():
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers()
# Create argument command
parser_update = subparsers.add_parser("sync", help="Sync local and remote repos")
parser_update.set_defaults(func=f) # <-- notice it's `f` not `f()`
options = parser.parse_args()
options.func(options)
if __name__ == "__main__":
main()
As an aside, you will have more problems with your snippet as you are defining the same parameter (--sync) in multiple places. When using subparsers it is customary to make these positional (no leading --) so they act as subcommands.
Here is a typical command line that I would use with subcommands:
import sys
import argparse
def f(args):
print("In func f")
print(args)
def g(args):
print("In func g")
print(args)
def main():
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers(dest="command")
parser_update = subparsers.add_parser("sync", help="Sync local and remote repos")
parser_update.set_defaults(func=f)
parser_delete = subparsers.add_parser("delete", help="Delete sub-command")
parser_delete.set_defaults(func=g)
options = parser.parse_args()
if options.command is not None:
options.func(options)
else:
parser.print_help()
parser.exit()
if __name__ == "__main__":
main()

Argparse with action='store_true' not working as expected

The idea is to add a flag (--slack, or -s) when running the script, so that I don't have to comment out the rep.post_report_to_slack() method every time I don't want to use it. When I run:
$ python my_script.py --slack
I get the error:
my_script.py: error: unrecognized arguments: --slack
Here's the code:
def main():
gc = Google_Connection()
meetings = gc.meetings
rep = Report(meetings)
if args.slack:
rep.post_report_to_slack()
print('posted to slack')
if __name__ == '__main__':
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('-s', '--slack', help='post to slack',
action='store_true')
args = parser.parse_args()
main()
Your code works, but it relies on args being available in the module namespace, which isn't great because, for one thing, it means you can't use your function without calling the script from the command line. A more flexible and conventional approach would be to write the function to accept whatever arguments it needs, and then pass everything you get from argparse to the function:
# imports should usually go at the top of the module
import argparse
def get_meeting_report(slack=False):
gc = Google_Connection()
meetings = gc.meetings
rep = Report(meetings)
if slack:
rep.post_report_to_slack()
print('posted to slack')
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('-s', '--slack', help='post to slack',
action='store_true')
args = parser.parse_args()
args = vars(args)
get_meeting_report(**args)
Now you can also more easily use your function outside of argparse by calling it directly.

argparse not getting triggered

I'm trying to use the Python argparse module to check argument parameters:
import argparse
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Example with non-optional arguments')
parser.add_argument('count', action="store", type=int)
parser.add_argument('units', action="store")
print 'test'
When I run the script (python test.py some inches), it just prints the output 'test' but the argparse module is not being triggered.
You need to actually call it!
import argparse
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Example with non-optional arguments')
parser.add_argument('count', action="store", type=int)
parser.add_argument('units', action="store")
args = parser.parse_args()
print args
You have to parse the args for this to work. You either need to call parser.parse_args() or parser.parse_known_args(). More info can be found here:
https://docs.python.org/3/library/argparse.html#argparse.ArgumentParser.parse_args

how to argparse have argument print a string and do nothing else

I want to have an argument --foobar using Python argparse, so that whenever this argument appears, the program prints a particular string and exits. I don't want to consume any other arguments, I don't want to check other arguments, nothing.
I have to call add_argument somehow, and then perhaps, from parse_args() get some information and based on that, print my string.
But even though I successfully used argparse before, I am surprised to find I have trouble with this one.
For example, none of the nargs values seem to do what I want, and none of the action values seem to fit. They mess up with the other arguments, which I want to ignore once this one is seen.
How to do it?
Use a custom action= parameter:
import argparse
class FoobarAction(argparse.Action):
def __init__(self, option_strings, dest, **kw):
self.message = kw.pop('message', 'Goodbye!')
argparse.Action.__init__(self, option_strings, dest, **kw)
self.nargs = 0
def __call__(self, parser, *args, **kw):
print self.message
parser.exit()
p = argparse.ArgumentParser()
p.add_argument('--ip', nargs=1, help='IP Address')
p.add_argument('--foobar',
action=FoobarAction,
help='Abort!')
p.add_argument('--version',
action=FoobarAction,
help='print the version number and exit!',
message='1.2.3')
args = p.parse_args()
print args
Reference: https://docs.python.org/2.7/library/argparse.html#action-classes
EDIT:
It looks like there is already an action= that does exactly what FoobarAction does. action='version' is the way to go:
import argparse
p = argparse.ArgumentParser()
p.add_argument('--foobar',
action='version',
version='Goodbye!',
help='Abort!')
args = p.parse_args()
print args
I'm just going to post this here, if it helps then great!
import argparse
parser = argparse.ArgumentParser(description='')
parser.add_argument('-foobar', '--foobar', help='Description for foobar argument',
required=False)
args = vars(parser.parse_args())
if args['foobar'] == 'yes':
foobar()
Usage:
python myscrip.py -foobar yes
Use action='store_true' (see the docs).
arg_test.py:
import argparse
import sys
p = argparse.ArgumentParser()
p.add_argument('--foobar', action='store_true')
args = p.parse_args()
if args.foobar:
print "foobar"
sys.exit()
Usage:
python arg_test.py --foobar
Result:
foobar

The python's argparse errors

where report this error : TypeError: 'Namespace' object is not iterable
import argparse
def parse_args():
parser = argparse.ArgumentParser(add_help=True)
parser.add_argument('-a', '--aa', action="store_true", default=False)
parser.add_argument('-b', action="store", dest="b")
parser.add_argument('-c', action="store", dest="c", type=int)
return parser.parse_args()
def main():
(options, args) = parse_args()
if __name__ == '__main__':
main()
Your issue has to do with this line:
(options, args) = parse_args()
Which seems to be an idiom from the deprecated "optparse".
Use the argparse idiom without "options":
import argparse
parser = argparse.ArgumentParser(description='Do Stuff')
parser.add_argument('--verbosity')
args = parser.parse_args()
Try:
args = parse_args()
print args
Results:
$ python x.py -b B -aa
Namespace(aa=True, b='B', c=None)
It's exactly like the error message says: parser.parse_args() returns a Namespace object, which is not iterable. Only iterable things can be 'unpacked' like options, args = ....
Though I have no idea what you were expecting options and args, respectively, to end up as in your example.
The error is in that parse_argv option is not required or used, only argv is passed.
Insted of:
(options, args) = parse_args()
You need to pass
args = parse_args()
And the rest remains same.
For calling any method just make sure of using argv instead of option.
For example:
a = argv.b
The best way (for me) to operate on args, where args = parser.parse_args()
is using args.__dict__. It's good, for example, when you want to edit arguments.
Moreover, it's appropriate to use long notation in your arguments, for example '--second' in '-a' and '--third' in '-b', as in first argument.
If you want to run 'main' you can should miss 'options', but it was said earlier.

Categories