argparse python模块的文档虽然非常棒,但对于我这个初学者来说,现在还难以理解。我不需要在命令行上做数学运算,也不需要在屏幕上修改格式行或更改选项字符。我想做的就是“如果arg是A,做这个,如果B做那个,如果以上都没有显示帮助并退出”。


当前回答

这是一个新手,但是将Python与Powershell结合起来并使用这个模板,灵感来自深入而伟大的Python命令行参数-真正的Python

在init_argparse()中可以做很多事情,这里我只介绍最简单的场景。

import argparse use if __name__ == "__main__": main() pattern to execute from terminal parse arguments within the main() function that has no parameters as all define a init_argparse() function create a parser object by calling argparse.ArgumentParser() declare one or more argumnent with parser.add_argument("--<long_param_name>") return parser parse args by creating an args object by calling parser.parse_args() define a function proper with param1, param2, ... call function_proper with params being assigned as attributes of an args object e.g. function_proper(param1=args.param1, param2=args.param2) within a shell call the module with named arguments: e.g. python foobar.py --param1="foo" --param2=="bar"

#file: foobar.py
import argparse

def function_proper(param1, param2):
    #CODE...

def init_argparse() -> argparse.ArgumentParser:
    parser = argparse.ArgumentParser()
    parser.add_argument("--param1")
    parser.add_argument("--param2")
    return parser


def main() -> None:
    parser = init_argparse()
    args = parser.parse_args()
    function_proper(param1=args.param1, param2=args.param2)


if __name__ == "__main__":
    main()
>>> python .\foobar.py --param1="foo" --param2=="bar"

其他回答

Matt正在询问argparse中的位置参数,我同意Python文档在这方面是缺乏的。在大约20多页的文章中,没有一个完整的例子同时展示了解析和使用位置参数。

这里的其他答案都没有显示位置参数的完整示例,所以这里有一个完整的示例:

# tested with python 2.7.1
import argparse

parser = argparse.ArgumentParser(description="An argparse example")

parser.add_argument('action', help='The action to take (e.g. install, remove, etc.)')
parser.add_argument('foo-bar', help='Hyphens are cumbersome in positional arguments')

args = parser.parse_args()

if args.action == "install":
    print("You asked for installation")
else:
    print("You asked for something other than installation")

# The following do not work:
# print(args.foo-bar)
# print(args.foo_bar)

# But this works:
print(getattr(args, 'foo-bar'))

让我困惑的是argparse将命名参数“——foo-bar”转换为“foo_bar”,但是名为“foo-bar”的位置参数仍然是“foo-bar”,这使得在程序中如何使用它变得不那么明显。

注意示例末尾的两行——这两行都不能获取foo-bar位置参数的值。第一个显然是错误的(它是一个算术表达式。Foo - bar),但第二个也不行:

AttributeError: 'Namespace' object has no attribute 'foo_bar'

如果希望使用foo-bar属性,必须使用getattr,如示例的最后一行所示。疯狂的是,如果你试图使用dest=foo_bar将属性名更改为更容易访问的名称,你会得到一个非常奇怪的错误消息:

ValueError: dest supplied twice for positional argument

下面是上面例子的运行方式:

$ python test.py
usage: test.py [-h] action foo-bar
test.py: error: too few arguments

$ python test.py -h
usage: test.py [-h] action foo-bar

An argparse example

positional arguments:
  action      The action to take (e.g. install, remove, etc.)
  foo-bar     Hyphens are cumbersome in positional arguments

optional arguments:
  -h, --help  show this help message and exit

$ python test.py install foo
You asked for installation
foo

作为现有答案的补充,如果你足够懒惰,可以使用称为protoargs的代码生成工具。它从配置生成参数解析器。对于python,它使用argparse。

配置可选A和B:

syntax = "proto2";
message protoargs
{
    optional string A     = 1; // A param description
    optional string B     = 2; // B param description
}//protoargs

配置所需的A和B:

syntax = "proto2";
message protoargs
{
    required string A     = 1; // A param description
    required string B     = 2; // B param description
}//protoargs

位置A和B的构型:

syntax = "proto2";
message protoargs
{
    required string A     = 1; // A param description
    required string B     = 2; // B param description
}//protoargs
message protoargs_links
{
}//protoargs_links

现在你要做的就是:

python ./protoargs.py -i test.proto -o . --py

并使用它(这里可以举其他例子):

import sys
import test_pa

class ArgsParser:
    program = "test"
    description = "Simple A and B parser test."

    def parse(self, argv):
        self.config = test_pa.parse(self.program, self.description, argv)

    def usage(self):
        return test_pa.usage(self.program, self.description)

if __name__ == "__main__":
    parser = ArgsParser()

    if len(sys.argv) == 1:
        print(parser.usage())
    else:
        parser.parse(sys.argv[1:])

        if parser.config.A:
            print(parser.config.A)

        if parser.config.B:
            print(parser.config.B)

如果你想要更多的改变配置,重新生成解析器,使用更新的parser.config。

UPD:正如规则中提到的,我必须指定这是我自己的项目

注意Python HOWTOs中的Argparse教程。它从最基本的例子开始,比如这个:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", type=int,
                    help="display a square of a given number")
args = parser.parse_args()
print(args.square**2)

然后发展到不那么基本的。

这里有一个预定义选项的例子,就像问的那样:

import argparse
parser = argparse.ArgumentParser()
parser.add_argument("square", type=int,
                    help="display a square of a given number")
parser.add_argument("-v", "--verbosity", type=int, choices=[0, 1, 2],
                    help="increase output verbosity")
args = parser.parse_args()
answer = args.square**2
if args.verbosity == 2:
    print("the square of {} equals {}".format(args.square, answer))
elif args.verbosity == 1:
    print("{}^2 == {}".format(args.square, answer))
else:
    print(answer)

最简单的答案!

附注:编写argparse文档的人是愚蠢的

python代码:

import argparse
parser = argparse.ArgumentParser(description='')
parser.add_argument('--o_dct_fname',type=str)
parser.add_argument('--tp',type=str)
parser.add_argument('--new_res_set',type=int)
args = parser.parse_args()
o_dct_fname = args.o_dct_fname
tp = args.tp
new_res_set = args.new_res_set

运行代码

python produce_result.py --o_dct_fname o_dct --tp father_child --new_res_set 1

argparse文档相当不错,但遗漏了一些可能不明显的有用细节。(@Diego Navarro已经提到了一些,但我会试着稍微扩展一下他的答案。)基本用法如下:

parser = argparse.ArgumentParser()
parser.add_argument('-f', '--my-foo', default='foobar')
parser.add_argument('-b', '--bar-value', default=3.14)
args = parser.parse_args()

从parse_args()返回的对象是一个“Namespace”对象:其成员变量以命令行参数命名的对象。Namespace对象是你访问参数和与它们相关的值的方式:

args = parser.parse_args()
print (args.my_foo)
print (args.bar_value)

(请注意,argparse在命名变量时用下划线替换参数名中的'-'。)

在许多情况下,您可能希望将参数简单地用作不带值的标志。你可以像这样在argparse中添加它们:

parser.add_argument('--foo', action='store_true')
parser.add_argument('--no-foo', action='store_false')

上面的代码将分别创建值为True的变量'foo'和值为False的变量'no_foo':

if (args.foo):
    print ("foo is true")

if (args.no_foo is False):
    print ("nofoo is false")

还要注意,你可以在添加参数时使用"required"选项:

parser.add_argument('-o', '--output', required=True)

这样,如果你在命令行中忽略了这个参数,argparse会告诉你它缺失了,并停止脚本的执行。

最后,请注意,可以使用vars函数创建参数的dict结构,如果这使您的生活更容易的话。

args = parser.parse_args()
argsdict = vars(args)
print (argsdict['my_foo'])
print (argsdict['bar_value'])

如你所见,vars返回一个dict,参数名作为键,值作为值。

还有许多其他选项和可以做的事情,但这应该涵盖最基本的常见使用场景。