这是我的提名; 它使用简单的解析器,将自定义内容放在
Package
类中。
它可以像这样调用:
python prog.py -p 0 1 2 --package 2 3 4
其中-p
或--package
后面跟随3个值,并且可以重复使用(action
为'append')。nargs=3
确保每个-p
后面都跟着3个值(否则解析器会引发错误)。将这些值转换为数字(并引发错误)是Package
类的责任。该类已经对非负value
进行了检查。
import argparse
class Package():
def __init__(self, id, value, tag):
self.id = int(id)
self.value = float(value)
if self.value <= 0:
raise ValueError("Amount must be greater than 0")
self.tag = int(tag)
def __repr__(self):
return 'Package (%s, %s, %s)'%(self.id, self.value, self.tag)
def main(argv):
parser = argparse.ArgumentParser()
parser.add_argument('-p', '--package', nargs=3, action='append', default=[],
metavar=('ID','Value','tag'), help='package parameters; may repeat')
args = parser.parse_args(argv)
print args
packages = [Package(*v) for v in args.package]
return packages
if __name__ == '__main__':
import sys
if sys.argv[1:]:
print main(sys.argv[1:])
else:
print main([])
print main('-p 1 2 3'.split())
print main('-p 0 1 2 --pack 2 3 4'.split())
print main(['-h'])
测试用例的一个样例运行结果如下:
2030:~/mypy$ python stack34823075.py
Namespace(package=[])
[]
Namespace(package=[['1', '2', '3']])
[Package (1, 2.0, 3)]
Namespace(package=[['0', '1', '2'], ['2', '3', '4']])
[Package (0, 1.0, 2), Package (2, 3.0, 4)]
usage: stack34823075.py [-h] [-p ID Value tag]
optional arguments:
-h, --help show this help message and exit
-p ID Value tag, --package ID Value tag
package parameters; may repeat
注意
metavar
如何影响帮助显示。
Package
的
__repr__
方法产生了一个漂亮的列表显示。
使用非数字的标签
运行的示例:
2038:~/mypy$ python stack34823075.py -p 1 2.3 tag
Namespace(package=[['1', '2.3', 'tag']])
Traceback (most recent call last):
File "stack34823075.py", line 31, in <module>
print main(sys.argv[1:])
File "stack34823075.py", line 20, in main
packages = [Package(*v) for v in args.package if v is not None]
File "stack34823075.py", line 10, in __init__
self.tag = int(tag)
ValueError: invalid literal for int() with base 10: 'tag'
一种特殊的
type
函数在这里无法正常工作。它将分别应用于这三个字符串,而不是作为一个整体。
自定义
Action
类可以处理这三个值,将每个值转换为
int
、
float
和
int
。但即使如此,我仍然更喜欢将它们传递给
Package
。
def __call__(self, namespace, dest, values):
new_value = Package(*values)
setattr(namespace, dest, new_value)
但是由于packages = [Package(*v) for v in args.package]
非常简单,我认为没有必要定制解析器或其操作。
python test.py --initializer="1" --packages ="[(1, 1.00), (2, 2.00)]"
- Brosef