I wanted to create a commandline-like / shell-like interface in python3.
Argparse seems to do the job of parsing and displaying the help/error messages. According to the python3 documentation of argparse, there is a func= argument that can be used to get your function called by argparse.
# sub-command functions
def foo(args):
print(args.x * args.y)
def bar(args):
print('((%s))' % args.z)
# create the top-level parser
parser = argparse.ArgumentParser()
subparsers = parser.add_subparsers()
# create the parser for the "foo" command
parser_foo = subparsers.add_parser('foo')
parser_foo.add_argument('-x', type=int, default=1)
parser_foo.add_argument('y', type=float)
parser_foo.set_defaults(func=foo)
# create the parser for the "bar" command
parser_bar = subparsers.add_parser('bar')
parser_bar.add_argument('z')
parser_bar.set_defaults(func=bar)
But as far as I can tell help_parser.set_defaults(func=foo)
does not call my funciton. It would be appreciated if you could help me.
You can reproduce the issue by running the program with python3, typing help
and then press [Enter]. It does not print hello
as expected.
Thanks!
def foo():
print('hello')
class Console:
def __init__(self):
"""Console like interface for navigating and interacting with the external file system."""
parser = argparse.ArgumentParser(
description='Console like interface for navigating and interacting with the external file system.',
add_help=False)
subparsers = parser.add_subparsers(dest='command')
subparsers.required = True
help_parser = subparsers.add_parser('help')
help_parser.add_argument('-x', type=int, default=1)
help_parser.set_defaults(func=foo)
setting_parser = subparsers.add_parser('settings')
setting_subparsers = setting_parser.add_subparsers(dest='settings_command')
setting_subparsers.required = True
setting_save_parser = setting_subparsers.add_parser('save', help='Save the current settings in a .json file.')
setting_save_parser.add_argument('file', type=str, nargs='?', default='settings.json')
setting_load_parser = setting_subparsers.add_parser('load', description='Load the last settings from a .json file.')
setting_load_parser.add_argument('file', type=str, nargs='?', help='settings.json')
setting_set_parser = setting_subparsers.add_parser('set')
setting_set_parser.add_argument('--host', type=str, required=True)
setting_set_parser.add_argument('-u', '--username', type=str, required=True)
setting_set_parser.add_argument('-p', '--password', type=str, required=True)
setting_set_parser.add_argument('-x', '--proxy', type=str, required=False)
while True:
try:
print('', flush=True, sep='')
data = input('>>>').split(' ')
print('your command:', data)
parser.parse_args(data)
except SystemExit:
pass
if __name__ == '__main__':
"""Spawn an commandline like interface."""
c = Console()
I found out how to make it work: The
args.func()
will call the function that got selected by argparse.Commandline log:
Actually
argparse
won't call the method automatically - you have to do it yourself. All it does it adds the method to thefunc
attribute of the args. So, what you could do is to check iffunc
attribute exists and then invoke it as following: