我想知道如何使用Python创建灵活的CLI界面。到目前为止,我已经提出以下建议:
$ cat cat.py
#!/usr/bin/env python
from sys import stdin
from fileinput import input
from argparse import ArgumentParser, FileType
def main(args):
for line in input():
print line.strip()
if __name__ == "__main__":
parser = ArgumentParser()
parser.add_argument('FILE', nargs='?', type=FileType('r'), default=stdin)
main(parser.parse_args())
它处理stdin和文件输入:
$ echo 'stdin test' | ./cat.py
stdin test
$ ./cat.py file
file test
问题是它没有按照我想要的方式处理多个输入或没有输入:
$ ./cat.py file file
usage: cat.py [-h] [FILE]
cat.py: error: unrecognized arguments: file
$ ./cat.py
对于多个输入,它应该多次cat
文件,对于没有输入输入,理想情况下应该具有与-h
相同的行为:
$ ./cat.py -h
usage: cat.py [-h] [FILE]
positional arguments:
FILE
optional arguments:
-h, --help show this help message and exit
有关使用Python创建灵活CLI界面的任何想法吗?
答案 0 :(得分:4)
使用nargs='*'
允许0个或多个参数:
if __name__ == "__main__":
parser = ArgumentParser()
parser.add_argument('FILE', nargs='*', type=FileType('r'), default=stdin)
main(parser.parse_args())
现在的帮助输出是:
$ bin/python cat.py -h
usage: cat.py [-h] [FILE [FILE ...]]
positional arguments:
FILE
optional arguments:
-h, --help show this help message and exit
当没有给出参数时,使用stdout
。
如果您想要至少需要一个FILE
参数,请改用nargs='+'
,但默认会被忽略,因此您可以删除它:
if __name__ == "__main__":
parser = ArgumentParser()
parser.add_argument('FILE', nargs='+', type=FileType('r'))
main(parser.parse_args())
现在不指定命令行参数给出:
$ bin/python cat.py
usage: cat.py [-h] FILE [FILE ...]
cat.py: error: too few arguments
您仍然可以通过传递stdin
作为参数来指定-
:
$ echo 'hello world!' | bin/python cat.py -
hello world!
答案 1 :(得分:2)
一个非常好的CLI界面,处理文件输入,标准输入,无输入,文件输出和就地编辑:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
def main(args, help):
'''
Simple line numbering program to demonstrate CLI interface
'''
if not (select.select([sys.stdin,],[],[],0.0)[0] or args.files):
help()
return
if args.output and args.output != '-':
sys.stdout = open(args.output, 'w')
try:
for i, line in enumerate(fileinput.input(args.files, inplace=args.inplace)):
print i + 1, line.strip()
except IOError:
sys.stderr.write("%s: No such file %s\n" %
(os.path.basename(__file__), fileinput.filename()))
if __name__ == "__main__":
import os, sys, select, argparse, fileinput
parser = argparse.ArgumentParser()
parser.add_argument('files', nargs='*', help='input files')
group = parser.add_mutually_exclusive_group()
group.add_argument('-i', '--inplace', action='store_true',
help='modify files inplace')
group.add_argument('-o', '--output',
help='output file. The default is stdout')
main(parser.parse_args(), parser.print_help)
代码只是模拟nl
并对行进行编号,但应该作为许多应用程序的良好框架。