argparse 函数参数

argparse function arguments

我正在尝试使用 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 函数的方法。

例如:

./pipeline -b

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

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

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

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

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

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

将您的代码缩减为:

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 的调用是错误的。它与方法的定义不匹配。

提供 'directory' 也无济于事,因为 -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 (默认)或位置用法。您是否尝试做一些更复杂的事情?

我同意@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)