python argparse bool_关于python:简单argparse示例需要:1个参数,3个结果

argparse python模块的文档虽然很好,但我确信,对于我的初学者来说,现在太多了,我无法理解。我不需要在命令行上做数学运算,也不需要干预屏幕上的格式化行或更改选项字符。我所要做的就是"如果arg是a,那么做这个,如果b做那个,如果上面没有显示帮助并退出"。

那就查一下sys.argv你想要的论点……

试过普拉斯吗?它是一个易于使用的argparse包装器,带有大量文档。

不是你。这是AgPARSE。它试图带你去星星之旅,而不在乎你要去哪里。

又是疯狂的"Python"API:/

祝福你,马特·威尔基,因为他在任何地方都是为初学者的小脑袋而奋斗。

在Python中,最迫切需要的是一个支持argparse/getopts声明形式的库。它允许两行获取所有选项并循环文件(如果没有给出文件,则为stdin),类似于Perl的getopts('abc:d:'); while (< >) {...}。与此简单且广泛使用的构造类似的python需要多行非简单代码,这些代码必须以太多脚本的方式重复。

相关:为什么使用argparse而不是optparse?

不,文件是垃圾。大多数python文档都是。

非常糟糕,这个argparse文档

以下是我使用argparse的方法(使用多个参数):

parser = argparse.ArgumentParser(description='Description of your program')

parser.add_argument('-f','--foo', help='Description for foo argument', required=True)

parser.add_argument('-b','--bar', help='Description for bar argument', required=True)

args = vars(parser.parse_args())

args将是一个包含以下参数的字典:

if args['foo'] == 'Hello':

# code here

if args['bar'] == 'World':

# code here

在您的情况下,只需添加一个参数。

正如我在对另一个答案的评论中所提到的,我希望保留argparse的自动帮助格式,但似乎没有一个选项可以有一个未经证实的参数(更可能的是,当我看到它时我不理解它),例如,一个需要做foo.py --action install或foo.py --action remove,而不是简单的foo.py install。

@Mattwillkie然后你必须定义一个位置参数,像这样:parser.add_argument('install', help='Install the app')(注意你不能用required=True定义位置参数)

@strongma parser.parse_args()是一个名称空间,我的args局部变量是一个dict,因为vars(parser.parse_args())返回一个dict,它是完全不可重写的。

作为argparse的一个noob,这个答案真的很有帮助,因为我不知道在它们被传递之后在哪里找到选项。换言之,我需要了解argsdict是如何如上所述生成的。

'-f'和'-b'有什么意义?为什么你不能省略这个?

@用户2763361您可以省略-f和-b,这对--foo和--bar都是定义"可选"参数的有效方法(docs.python.org/2/library/argparse.html add参数me&zwnj;&8203;thod)

直接从命令行调用程序时使用"短格式",在脚本中运行程序/命令时使用"长格式"。在这种情况下,长格式的代码更容易被人阅读,因此更容易遵循代码/脚本的逻辑。

就我个人而言,我发现更容易访问参数,比如args.foo和args.bar,而不是字典语法。当然,这两种方法都可以,但args实际上不是一个字典,而是一个argparse.Namespace对象。

我对原始问题的理解是双重的。首先,对于最简单的argparse示例,我很惊讶在这里没有看到它。当然,简单地说,这也是所有的开销和小功率,但它可能会让你开始。

import argparse

parser = argparse.ArgumentParser()

parser.add_argument("a")

args = parser.parse_args()

if args.a == 'magic.name':

print 'You nailed it!'

但是这个位置参数现在是必需的。如果您在调用这个程序时忽略了它,您将得到一个关于缺少参数的错误。这就引出了最初问题的第二部分。MattWilkie似乎想要一个没有命名标签(选项标签)的可选参数。我的建议是将上述代码修改如下:

...

parser.add_argument("a", nargs='?', default="check_string_for_empty")

...

if args.a == 'check_string_for_empty':

print 'I can tell that no argument was given and I can deal with that here.'

elif args.a == 'magic.name':

print 'You nailed it!'

else:

print args.a

可能会有一个更优雅的解决方案,但这是可行的,而且是极简主义的。

经过一段时间的思考,我总结出这个问题实际上最能回答被问到的问题和当时的困境。其他优秀的答案已经获得了足够多的代表来证明他们的价值,并能承受一点竞争。-)

@巴纳克:这是你想要的,无论"A"代表什么。如果需要一个参数(例如文件名),则它是在命令行中作为文件名输入的。然后,您可以自己进行处理以确定文件系统中是否存在该文件,但这是另一个问题。

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对象是访问参数及其相关值的方式:

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

上面将分别创建名为"foo"且值为true和"no foo"且值为false的变量:

if (args.foo):

print"foo is true"

if (args.no_foo is False):

print"nofoo is false"

还请注意,添加参数时可以使用"必需"选项:

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,其中参数名作为键,其值为,er,值。

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

'-f'和'-b'有什么意义?为什么你不能省略这个?

对于每个运行时选项,都有一个"短格式"(一个破折号)和一个"长格式"(两个破折号)版本是相当传统的。例如,在几乎所有标准的Unix/Linux实用程序中,您都会看到这一点;使用man cp或man ls,您会发现有许多选项都有两种风格(例如-f, --force)。人们喜欢其中一种或另一种的原因可能有很大的不同,但无论如何,在程序中使用这两种形式都是相当标准的。

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位置参数的值。第一个显然是错误的(它是一个算术表达式args.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

根据stackoverflow.com/questions/4480075/&hellip,nargs='?'是"可选位置"的咒语;

位置foo-bar没有转换成foo_bar的事实在bugs.python.org/issue1525中得到了解决。

我认为解决这个bug的一个更简单的方法是将参数称为"foo-bar",而不是"foo-bar",然后使用print args.foo_bar。因为它是一个位置参数,所以在调用脚本时不必指定名称,所以对用户来说并不重要。

@Luator你说得对,重新命名这个论点很容易,但是bug报告的作者提出了一个很好的例子,那就是由于不必要的认知负荷,这仍然是一个错误。使用argparse时,必须暂停并调用选项和参数的不同命名约定。请参见bugs.python.org/msg164968。

@我完全同意这是一个应该修复的错误。我只是认为重命名参数比使用getattr更容易,也更不容易混淆(它也更灵活,因为它允许您将参数从可选更改为位置,而不必更改使用值的代码)。

另一个概要介绍,受本文启发。

import argparse

# define functions, classes, etc.

# executes when your script is called from the command-line

if __name__ =="__main__":

parser = argparse.ArgumentParser()

#

# define each option with: parser.add_argument

#

args = parser.parse_args() # automatically looks at sys.argv

#

# access results with: args.argumentName

#

参数由以下组合定义:

parser.add_argument( 'name', options... )              # positional argument

parser.add_argument( '-x', options... )                # single-char flag

parser.add_argument( '-x', '--long-name', options... ) # flag with long name

常见的选项有:

帮助:使用--help时此参数的说明。

默认值:省略参数时的默认值。

类型:如果您希望使用float或int(否则为str)。

dest:给一个旗子取一个不同的名字(如'-x', '--long-name', dest='longName')。注:默认情况下,--long-name通过args.long_name访问。

操作:用于特殊处理某些参数

store_true, store_false:用于布尔型参数'--foo', action='store_true' => args.foo == True。

store_const:与选项const'--foo', action='store_const', const=42 => args.foo == 42一起使用。

count:重复期权,如./myscript.py -vv'-v', action='count' => args.v == 2所述。

append:重复期权,如./myscript.py --foo 1 --foo 2'--foo', action='append' => args.foo == ['1', '2']所述。

必需:如果需要标志,或者位置参数不是。

n args:用于捕获n个args ./myscript.py --foo a b => args.foo = ['a', 'b']

选择:限制可能的输入(指定为字符串列表,或者如果是type=int)。

以下是我在学习项目中的想法,主要归功于@dmh…

演示代码:

import argparse

def main():

parser = argparse.ArgumentParser()

parser.add_argument('-f', '--flag', action='store_true', default=False)  # can 'store_false' for no-xxx flags

parser.add_argument('-r', '--reqd', required=True)

parser.add_argument('-o', '--opt', default='fallback')

parser.add_argument('arg', nargs='*') # use '+' for 1 or more args (instead of 0 or more)

parsed = parser.parse_args()

# NOTE: args with '-' have it replaced with '_'

print('Result:',  vars(parsed))

print('parsed.reqd:', parsed.reqd)

if __name__ =="__main__":

main()

这可能已经发展,可以在线使用:command-line.py

为代码提供训练的脚本:command-line-demo.sh

最后是一个有意义的argparse示例

请注意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)

很高兴看到文档已经更新。我向你保证,5年前OP发布这个问题时,情况并非如此。

您也可以使用plac(一个围绕argparse的包装)。

作为奖励,它生成了简洁的帮助说明-见下文。示例脚本:

#!/usr/bin/env python3

def main(

arg: ('Argument with two possible values', 'positional', None, None, ['A', 'B'])

):

"""General help for application"""

if arg == 'A':

print("Argument has value A")

elif arg == 'B':

print("Argument has value B")

if __name__ == '__main__':

import plac

plac.call(main)

实例输出:

未提供参数-example.py:

usage: example.py [-h] {A,B}

example.py: error: the following arguments are required: arg

提供了意外的参数-example.py C:

usage: example.py [-h] {A,B}

example.py: error: argument arg: invalid choice: 'C' (choose from 'A', 'B')

提供了正确的参数-example.py A:

Argument has value A

全帮助菜单(自动生成)-example.py -h:

usage: example.py [-h] {A,B}

General help for application

positional arguments:

{A,B}       Argument with two possible values

optional arguments:

-h, --help  show this help message and exit

简短说明:

参数名通常等于参数名(arg)。

arg参数后的tuple注释具有以下含义:

说明(Argument with two possible values)

参数类型-"flag"、"option"或"positional"之一(positional)

缩写(None)

参数值类型-例如float、string(None)

限制选择集(['A', 'B'])

文档:

要了解更多关于使用plac的信息,请查看其重要文档:

Plac: Parsing the Command Line the Easy Way

加上其他人的陈述:

我通常喜欢使用"dest"参数指定变量名,然后使用"globals().update()"将这些变量放入全局命名空间。

用途:

$ python script.py -i"Hello, World!"

代码:

...

parser.add_argument('-i', '--input', ..., dest='inputted_variable',...)

globals().update(vars(parser.parse_args()))

...

print(inputted_variable) # Prints"Hello, World!"

在内部,argparse使用getattr和setattr访问命名空间中的值。这样一来,它就不会被奇怪形成的dest值所困扰。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值