[英]Consistent way to redirect both stdin & stdout to files in python using optparse
I've got a dozen programs that can accept input via stdin or an option, and I'd like to implement the same features in a similar way for the output. 我有十几个可以通过stdin或选项接受输入的程序,我想以类似的方式为输出实现相同的功能。
The optparse code looks like this: optparse代码如下所示:
parser.add_option('-f', '--file',
default='-',
help='Specifies the input file. The default is stdin.')
parser.add_option('-o', '--output',
default='-',
help='Specifies the output file. The default is stdout.')
The rest of the applicable code looks like this: 其余适用的代码如下所示:
if opts.filename == '-':
infile = sys.stdin
else:
infile = open(opts.filename, "r")
if opts.output == '-':
outfile = sys.stdout
else:
outfile = open(opts.output, "w")
This code works fine and I like its simplicity - but I haven't been able to find a reference to anyone using a default value of '-' for output to indicate stdout. 这段代码运行正常,我喜欢它的简单性 - 但是我无法找到任何使用默认值' - '表示stdout的人的引用。 Is this a good consistent solution or am I overlooking something better or more expected?
这是一个很好的一致解决方案还是我忽略了更好或更期望的事情?
For input files you could use fileinput
module. 对于输入文件,您可以使用
fileinput
模块。 It follows common convention for input files: if no files given or filename is '-' it reads stdin, otherwise it reads from files given at a command-line. 它遵循输入文件的通用约定:如果没有给定文件或文件名是' - ',它将读取stdin,否则它将从命令行给出的文件中读取。
There is no need in -f
and --file
options. -f
和--file
选项不需要。 If your program always requires an input file then it is not an option. 如果您的程序总是需要输入文件,那么它不是一个选项。
-o
and --output
is used to specify the output file name in various programs . -o
和--output
用于指定各种程序中的输出文件名 。
#!/usr/bin/env python
import fileinput
import sys
from optparse import OptionParser
parser = OptionParser()
parser.add_option('-o', '--output',
help='Specifies the output file. The default is stdout.')
options, files = parser.parse_args()
if options.output and options.output != '-':
sys.stdout = open(options.output, 'w')
for line in fileinput.input(files):
process(line)
argparse
module allows you to specify explicitly files as arguments: argparse
模块允许您将文件显式指定为参数:
#!/usr/bin/env python
import fileinput
import sys
from argparse import ArgumentParser
parser = ArgumentParser()
parser.add_argument('files', nargs='*', help='specify input files')
group = parser.add_mutually_exclusive_group()
group.add_argument('-o', '--output',
help='specify the output file. The default is stdout')
group.add_argument('-i', '--inplace', action='store_true',
help='modify files inplace')
args = parser.parse_args()
if args.output and args.output != '-':
sys.stdout = open(args.output, 'w')
for line in fileinput.input(args.files, inplace=args.inplace):
process(line)
Note: I've added --inplace
option in the second example: 注意:我在第二个示例中添加了
--inplace
选项:
$ python util-argparse.py --help
usage: util-argparse.py [-h] [-o OUTPUT | -i] [files [files ...]]
positional arguments:
files specify input files
optional arguments:
-h, --help show this help message and exit
-o OUTPUT, --output OUTPUT
specify the output file. The default is stdout
-i, --inplace modify files inplace
If you can use argparse
(ie Python 2.7+), it has built-in support for what you want: straight from argparse
doc 如果你可以使用
argparse
(即Python 2.7+),它内置了对你想要的支持:直接来自argparse
doc
The
FileType
factory creates objects that can be passed to the type argument ofArgumentParser.add_argument()
.FileType
工厂创建可以传递给ArgumentParser.add_argument()
的type参数的对象。 Arguments that haveFileType
objects as their type will open command-line arguments […]FileType
objects understand the pseudo-argument '-' and automatically convert this into sys.stdin for readableFileType
objects andsys.stdout
for writableFileType
objects.将
FileType
对象作为其类型的参数将打开命令行参数[...]FileType
对象理解伪参数' - '并自动将其转换为sys.stdin以获取可读的FileType
对象,并将sys.stdout
为可写的FileType
对象。
So my advice is to simply use 所以我的建议是简单地使用
import sys
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('file', type=argparse.FileType('r'),
help="Specifies the input file")
parser.add_argument('output', type=argparse.FileType('w'),
help="Specifies the output file")
args = parser.parse_args(sys.argv[1:])
# Here you can use your files
text = args.file.read()
args.output.write(text)
# … and so on
Then you can do 那你可以做
> python spam.py file output
To read from file
and output to output
, or 从
file
和输出读取到output
,或
> echo "Ni!" | python spam.py - output
to read "Ni!"
读
"Ni!"
and output to output
, or 并输出到
output
,或
> python spam.py file -
… ...
And it's good, since using -
for the relevant stream is a convention that a lot of programs use . 这很好,因为使用
-
对于相关流是许多程序使用的约定 。 If you want to point it out, add it to the help
strings. 如果要指出它,请将其添加到
help
字符串中。
parser.add_argument('file', type=argparse.FileType('r'),
help="Specifies the input file, '-' for standard input")
For reference, the usage message will be 作为参考,使用消息将是
> python spam.py -h
usage: [-h] file output
positional arguments:
file Specifies the input file, '-' for standard input
output Specifies the output file, '-' for standard output
optional arguments:
-h, --help show this help message and exit
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.