如何使用 argparse 为函数应用选项

how to apply options for the functions using argparse

我有这样的功能

def add(x,y):
    print x+y

def square(a):
    print a**2

现在我正在使用 argparse 为这个函数定义 linux 命令(选项)。

我试过这个代码

import argparse
# Create Parser and Subparser
parser = argparse.ArgumentParser(description="Example ArgumentParser")
subparser = parser.add_subparsers(help="commands")

# Make Subparsers
add_parser = subparser.add_parser('--add', help="add func")
add_parser.add_argument("x",type=float,help='first number')
add_parser.add_argument("y",type=float,help='second number')
add_parser.set_defaults(func='add')

square_parser = subparser.add_parser('--square', help="square func")
square_parser.add_argument("a",type=float,help='number to square')
square_parser.set_defaults(func='square')

args = parser.parse_args()


def add(x,y):
  print x + y

def square(a):
  print a**2

if args.func == '--add':
  add(args.x,args.y)
if args.func == '--square':
  square(args.a)

但是我在传递命令时出错 python code.py --add 2 3

invalid choice: '2' (choose from '--add', '--square')

--addoptionals flag 的形式,add 是子解析器名称的正确形式

import argparse
# Create Parser and Subparser
parser = argparse.ArgumentParser(description="Example ArgumentParser")
subparser = parser.add_subparsers(dest='cmd', help="commands")

# Make Subparsers
add_parser = subparser.add_parser('add', help="add func")
add_parser.add_argument("x",type=float,help='first number')
add_parser.add_argument("y",type=float,help='second number')
add_parser.set_defaults(func='add')

square_parser = subparser.add_parser('square', help="square func")
square_parser.add_argument("a",type=float,help='number to square')
square_parser.set_defaults(func='square')

args = parser.parse_args()
print(args)

def add(x,y):
  print x + y

def square(a):
  print a**2

if args.func == 'add':    # if args.cmd=='add': also works
  add(args.x,args.y)
if args.func == 'square':
  square(args.a)

生产

0950:~/mypy$ python stack43557510.py add 2 3
Namespace(cmd='add', func='add', x=2.0, y=3.0)
5.0

我在 add_subparsers 命令中添加了 dest='cmd'print(args) 以提供更多信息。请注意,子解析器名称现在可用 args.cmd。所以你不需要添加 func

但是 argparse 文档确实建议使用 set_defaults

https://docs.python.org/3/library/argparse.html#sub-commands

add_parser.set_defaults(func=add)

有了这个args.func其实就是一个函数对象,而不仅仅是一个字符串名称。所以它可以用作

args.func(args)

请注意,我必须更改函数处理其参数的方式:

def add(args):
    print(args.x + args.y)

def square(args):
    print(args.a**2)

# Create Parser and Subparser
parser = argparse.ArgumentParser(description="Example ArgumentParser")
subparser = parser.add_subparsers(dest='cmd', help="commands")

# Make Subparsers
add_parser = subparser.add_parser('add', help="add func")
add_parser.add_argument("x",type=float,help='first number')
add_parser.add_argument("y",type=float,help='second number')
add_parser.set_defaults(func=add)

square_parser = subparser.add_parser('square', help="square func")
square_parser.add_argument("a",type=float,help='number to square')
square_parser.set_defaults(func=square)

args = parser.parse_args()
print(args)

args.func(args)

生产

1001:~/mypy$ python stack43557510.py add 2 3
Namespace(cmd='add', func=<function add at 0xb73fd224>, x=2.0, y=3.0)
5.0