argparse函数参数

时间:2018-03-21 14:11:20

标签: python python-3.x argparse

我正在尝试使用argparse创建带参数的脚本,但我无法使用。

我的脚本名称为pipeline,它有一些选项参数,如-b,-c,-i和-r。

如果你调用脚本./pipeline -b应该提出错误,要求提供git存储库路径,但我无法做到这一点。

from git import Repo
import os
import sys
import subprocess
import argparse

class Ci:

    def build(self,args):
        cloned_repo = Repo.clone_from(args)
        print("clonning repository " + args)
        cloned_repo

        dir = git.split('/')(-1)

        if os.path.isdir(dir):
            print("repository cloned successfully")
        else:
            print("error to clone repository")


if __name__ == '__main__':

    parser = argparse.ArgumentParser()

    parser.add_argument('-b','-build',action='store_true', help='execute mvn clean install')
    parser.add_argument('-c','-compress',action='store_true',help='zip a directory recursively')
    parser.add_argument('-i','-integration',action='store_true',help='execute mvn verify')
    parser.add_argument('-r','-release',action='store_true',help='execute build,integration and compress respectively')
    args = parser.parse_args()

    if args.b:
        a = Ci()
        a.build()

    if len(sys.argv) < 2:
        parser.print_help()
        sys.exit(1)

我无法使这个子参数工作,我找不到将此参数传递给build函数的方法。

e.g:

./pipeline -b

Output: error missins git path
./pipeline -b https://git/repo
Output: clonning repo

并且字符串"https://git/repo"必须作为参数传递给我的build函数:

我怎样才能让它发挥作用?

3 个答案:

答案 0 :(得分:3)

首先关于约定的注释:通常较长的选项名称前面有两个连字符,如'--build'

第二,'store_true'是您使用'-b'执行的操作,这意味着argparse并不期望在其后面有一个参数,它只是将args.build变量设置为True(和如果参数不存在,则会将其设置为False

尝试删除action='store_true',然后默认将它在参数列表中找到的下一个值存储到args.build

答案 1 :(得分:1)

我同意@hpaulj(为什么不接受答案?)。我猜您发现了问题所在,即store_true不接受参数,然后遵循hpaulj指示。

此外,由于标题的问题,我打开了这个问题,我期望下面的内容有所不同。我想找到一种方法将argparse参数传递给函数,并可能使用函数参数对其进行修改。这是我写的解决方案,以防其他人寻找它。可能需要调整它以解决位置参数,我还强调了使用vars(args)从argparse参数中获取字典以将dict-to-dict与args_dict比较的可能性:

def get_options(args_dict: dict):
    """ get options from command-line,
        update with function args_dict if needed """
    args = get_cmd()  # this is the function taking cmd-line arguments 
    for key, val in args_dict.items():
        if not hasattr(args, key):
            raise AttributeError('unrecognized option: ', key)
        else:
            setattr(args, key, val)
    return(args)

答案 2 :(得分:0)

将代码缩减为:

import argparse

class Ci:

    def build(self,args):
        print("clonning repository " + args)

if __name__ == '__main__':

    parser = argparse.ArgumentParser()

    parser.add_argument('-b','-build',action='store_true', help='execute mvn clean install')
    parser.add_argument('-c','-compress',action='store_true',help='zip a directory recursively')
    parser.add_argument('-i','-integration',action='store_true',help='execute mvn verify')
    parser.add_argument('-r','-release',action='store_true',help='execute build,integration and compress respectively')
    args = parser.parse_args()
    print(args)

    if args.b:
        a = Ci()
        a.build()

我明白了:

1313:~/mypy$ python3 stack49408644.py -b
Namespace(b=True, c=False, i=False, r=False)
Traceback (most recent call last):
  File "stack49408644.py", line 22, in <module>
    a.build()
TypeError: build() missing 1 required positional argument: 'args'

解析器运行正常,看到args.bTrue。但是对build的调用是错误的。它与方法的定义不匹配。

提供“目录”也无济于事,因为-bTrue/False

1313:~/mypy$ python3 stack49408644.py -b foo
usage: stack49408644.py [-h] [-b] [-c] [-i] [-r]
stack49408644.py: error: unrecognized arguments: foo

您需要更改-b以获取值,或者添加另一个带值的参数。

@AntiMatterDynamite展示了如何更改-b。相反,我们添加:

parser.add_argument('adir', help='a directory for build')

并更改build电话

    a.build(args.adir)

现在将值传递给方法:

1322:~/mypy$ python3 stack49408644.py -b
usage: stack49408644.py [-h] [-b] [-c] [-i] [-r] adir
stack49408644.py: error: the following arguments are required: adir
1322:~/mypy$ python3 stack49408644.py -b foo
Namespace(adir='foo', b=True, c=False, i=False, r=False)
clonning repository foo

而是重新定义-b

parser.add_argument('-b','-build', help='execute mvn clean install')

if args.b is not None:
    a = Ci()
    a.build(args.b)

测试运行:

1322:~/mypy$ python3 stack49408644.py -b
usage: stack49408644.py [-h] [-b B] [-c] [-i] [-r]
stack49408644.py: error: argument -b/-build: expected one argument
1324:~/mypy$ python3 stack49408644.py -b foo
Namespace(b='foo', c=False, i=False, r=False)
clonning repository foo

所以你的解析器需要接受一个值。您需要将该值传递给您的代码。您似乎已经阅读了足够多的argparse文档来获取print_helpstore_true之类的内容,但错过了store(默认)或位置的简单使用。你想做更复杂的事吗?