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

时间:2019-01-09 18:57:01

标签: python

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

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

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

我到目前为止所拥有的

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

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()

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

 python3 myutils.py

我没有收到任何错误。

当我这样做时:

 python3 myutils.py -h

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

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

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,就像这样:

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的定义,如下所示:

 def function1(lc,uc):
     assert(lc is not None)
     assert(uc is not None)
     print('made it here')
     return True

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

 python3 myutils.py function1 -lc 1 -uc 3

,但根本不调用function1。 我显然还缺了一个难题。

我认为我在代码末尾需要什么-在我调用parse_args()之后是这样的:(伪代码)

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

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

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

所以现在我有如下代码:

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列表将变得非常大。

2 个答案:

答案 0 :(得分:1)

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

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

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

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

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

答案 1 :(得分:0)

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

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

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))

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

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

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

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

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

输出:

4