argparse python模块的文档虽然非常棒,但对于我这个初学者来说,现在还难以理解。我不需要在命令行上做数学运算,也不需要在屏幕上修改格式行或更改选项字符。我想做的就是“如果arg是A,做这个,如果B做那个,如果以上都没有显示帮助并退出”。
当前回答
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
其他回答
注意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)
补充一下其他人已经说过的话:
我通常喜欢使用'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!"
作为现有答案的补充,如果你足够懒惰,可以使用称为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:正如规则中提到的,我必须指定这是我自己的项目
我对原问题的理解是双重的。首先,就最简单的argparse示例而言,我很惊讶在这里没有看到它。当然,为了简单起见,它也都是头顶上的,只有很少的电力,但它可能会让你开始。
import argparse
parser = argparse.ArgumentParser()
parser.add_argument("a")
args = parser.parse_args()
if args.a == 'magic.name':
print 'You nailed it!'
但是这个位置参数现在是必需的。如果在调用此程序时省略它,则会得到关于缺少参数的错误。这就引出了原问题的第二部分。Matt Wilkie似乎想要一个没有命名标签(——option标签)的可选参数。我的建议是将上面的代码修改如下:
...
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
也许有一个更优雅的解决方案,但这是可行的,而且是极简主义的。
下面是我使用argparse(使用多个args)的方法:
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
在您的情况下,只需添加一个参数。
推荐文章
- 有没有办法在python中做HTTP PUT
- “foo Is None”和“foo == None”之间有什么区别吗?
- 类没有对象成员
- Django模型“没有显式声明app_label”
- 熊猫能自动从CSV文件中读取日期吗?
- 在python中zip的逆函数是什么?
- 有效的方法应用多个过滤器的熊猫数据框架或系列
- 如何检索插入id后插入行在SQLite使用Python?
- 我如何在Django中添加一个CharField占位符?
- 如何在Python中获取当前执行文件的路径?
- 我如何得到“id”后插入到MySQL数据库与Python?
- super()失败,错误:TypeError "参数1必须是类型,而不是classobj"当父不继承对象
- Python内存泄漏
- 实现嵌套字典的最佳方法是什么?
- 如何在tensorflow中获得当前可用的gpu ?