python argparse:如何将特定参数与特定函数关联

python argparser: how do i associate specific arguments with specific functions

我对python和argparser库是新手。我试图弄清楚如何编写一个具有许多不同功能的脚本文件,每个功能都需要不同的参数。

因此,例如,我可能具有以下方法签名:

1
2
3
 def function1(a,b,c):
 def function2(x,y,z):
 def function3():

到目前为止我有什么

到目前为止,我已经将所有可能的参数添加为可选项,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import argparse

 def function1(lc,uc):
     assert(lc is not None)
     assert(uc is not None)
     #do something

 def function2():
     #do something else

 def function3(lr,ur):
     assert(lr is not None)
     assert(ur is not None)
     #do something else

parser = argparse.ArgumentParser(description='This is the description of my program')
parser.add_argument('-lc','--lower_create', type=int, help='lower range value for creating mailboxes')
parser.add_argument('-uc','--upper_create', type=int, help='upper range value for creating mailboxes')
parser.add_argument('-lr','--lower_reserve', type=int, help='lower range value for reserving mailboxes')
parser.add_argument('-ur','--upper_reserve', type=int, help='upper range value for reserving mailboxes')

args = parser.parse_args()

到目前为止,一切都很好。当我像这样运行脚本时:

1
 python3 myutils.py

我没有任何错误。

当我这样做时:

1
 python3 myutils.py -h

它给了我一个很好的帮助系统。

但是我不清楚的是如何将特定的args与特定的函数相关联。例如,这是我调用function1时遇到的错误:

1
2
3
4
lab-1:/var/www/localhost/htdocs/pvmaildbapp# python3 myutils.py function1
usage: myutils.py [-h] [-lc LOWER_CREATE] [-uc UPPER_CREATE]
                       [-lr LOWER_RESERVE] [-ur UPPER_RESERVE]
myutils.py: error: unrecognized arguments: function1

我还是第一次通过argparse文档,所以我确定我错过了一些东西。但是任何朝着正确方向的提示/指针将不胜感激

编辑1

根据d_kennetz和UtahJarhead(感谢您)的以下回答,我更改了代码,为每个参数包括一个"目标"参数,并且我还需要用户尝试调用的函数的arg,如下所示:

1
2
3
4
5
6
7
8
9
10
parser = argparse.ArgumentParser(description='This is the description of my program')

parser.add_argument('func_name',help='name of function you want to run')

parser.add_argument('-lc','--lower_create', type=int, dest='lc', help='lower range value for creating mailboxes')
parser.add_argument('-uc','--upper_create', type=int, dest='uc', help='upper range value for creating mailboxes')
parser.add_argument('-lr','--lower_reserve', type=int, dest='lr', help='lower range value for reserving mailboxes')
parser.add_argument('-ur','--upper_reserve', type=int, dest='ur', help='upper range value for reserving mailboxes')

args = parser.parse_args()

然后,我还更改了function1的定义,如下所示:

1
2
3
4
5
 def function1(lc,uc):
     assert(lc is not None)
     assert(uc is not None)
     print('made it here')
     return True

最后,我现在尝试像这样通过命令行调用:

1
 python3 myutils.py function1 -lc 1 -uc 3

但它根本不调用function1。
我显然还错过了另外一个难题。

我认为我在代码结尾处需要的内容-在我调用parse_args()之后是这样的:(pseudocode)

1
2
3
4
5
6
select case args.func_name
   case 'function1'
       make sure i have lc and uc
   case function3
       make sure i have lr and ur
end select

它是否正确?

编辑2

好的,我想我已经把所有的点都联系了。

  • 我肯定缺少保存该函数的位置参数
    用户要呼叫的名称。
  • 我仍在使用可选参数
    用于保存lc,uc等值的符号
  • 我所缺少的部分是用args手动匹配功能的逻辑。由于某种原因,我想我可以通过argparse库免费获得其中一些管道。
  • 所以现在我的代码看起来像这样:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    args = parser.parse_args()
    #print(args)
    if args.func_name == 'function1':
        #make sure we have lc and uc
        assert(args.lc is not None)
        assert(args.uc is not None)
        function1(args.lc, args.uc)
    elif args.func_name == 'function3':
        assert(args.lr is not None)
        assert(args.ur is not None)
        function3(args.lr, args.ur)
    elif args.func_name == 'function2':
        function2()

    该代码有效。但是我觉得可能有一种更优雅的方式来处理我拥有的最后一系列if / elifs ...随着此实用程序文件的增加以及我向其中添加的更多方法,if elif列表将变得非常大。


    您正在尝试使用必需的位置参数,但在argparse设置中未设置位置参数。要解决此问题,听起来您想添加以下额外的行:

    1
    parser.add_argument('func_name', help='function name')

    就这样,您已经创建了4个变量,分别为args.lower_createargs.upper_createargs.lower_reserveargs.upper_reserve。如果您传递了类似python3 myutils.py -lc 1234的内容,则args.lower_create的值将为1234

    编辑:我想也许您可能没有包括适当的输入。期望类似于以下内容:

    1
    python3 myutils.py -lc 0 -uc 1 -lr 2 -ur 3


    为了说明您在哪里出错了,您需要将目标传递给argparse参数,以便可以在代码中将其称为变量。其次,在诸如def function1(lc, uc):之类的函数调用中使用的变量将是该函数的局部变量,因此不会被解释为全局变量。这是一件好事,因为我们通常不希望将全局变量传递给函数调用(尽管有一些例外)。

    这是我对您的代码的修改:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    import argparse
    import sys

    parser = argparse.ArgumentParser(description='This is the description of my program')
    parser.add_argument('-lc','--lower_create', type=int, dest="lc", help='lower range value for creating mailboxes')
    parser.add_argument('-uc','--upper_create', type=int, dest="uc", help='upper range value for creating mailboxes')
    parser.add_argument('-lr','--lower_reserve', type=int, dest="lr", help='lower range value for reserving mailboxes')
    parser.add_argument('-ur','--upper_reserve', type=int, dest="ur", help='upper range value for reserving mailboxes')

    args = parser.parse_args()

    def function1(lc,uc):
        assert(lc is not None)
        assert(uc is not None)
        return True

    print(function1(args.lc, args.uc))

    首先,您看到我在parser.add_argument()调用中传递了一个名为dest=的选项。这将告诉python代码将在程序中调用该参数的内容。

    然后,我编写了您的函数,以在将值传递给函数时返回True

    最后,我对print的调用通过以下语法args.lc, args.uc调用了我的argparse dest=变量。这就是您在python代码中调用argparse参数的方式。

    最后,当我运行命令并传递值时:

    1
    $ python3.5 argfun.py -lc 4 -uc 0

    输出:

    1
    4