14

我有十几个可以通过标准输入或选项接受输入的程序,我想以类似的方式为输出实现相同的功能。

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

其余适用的代码如下所示:

if opts.filename == '-':
    infile = sys.stdin
else:
    infile = open(opts.filename, "r")

if opts.output == '-':
    outfile = sys.stdout
else:
    outfile = open(opts.output, "w")

这段代码运行良好,我喜欢它的简单性——但我无法找到对使用默认值“-”作为输出指示标准输出的任何人的引用。这是一个很好的一致解决方案,还是我忽略了更好或更预期的东西?

4

2 回答 2

15

对于输入文件,您可以使用fileinputmodule. 它遵循输入文件的通用约定:如果没有给出文件或文件名是'-',它读取标准输入,否则它从命令行给出的文件中读取。

-f--file选项中没有必要。如果您的程序总是需要输入文件,那么它不是一个选项。

-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模块允许您明确指定文件作为参数:

#!/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)

注意:我--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
于 2011-10-23T03:28:52.260 回答
12

如果您可以使用argparse(即 Python 2.7+),它具有对您想​​要的内容的内置支持:直接来自argparsedoc

FileType工厂创建可以传递给类型参数的对象ArgumentParser.add_argument()。以FileType对象为类型的参数将打开命令行参数 […]FileType对象理解伪参数“-”并自动将其转换为 sys.stdin 以用于可读FileType对象和sys.stdout可写FileType对象。

所以我的建议是简单地使用

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

然后你可以做

> python spam.py file output 

读取file并输出到output, 或

> echo "Ni!" | python spam.py - output  

读取"Ni!"并输出到output, 或

> python spam.py file -

…</p>

这很好,因为使用-相关流是很多程序使用的约定。如果您想指出它,请将其添加到help字符串中。

  parser.add_argument('file', type=argparse.FileType('r'),
    help="Specifies the input file, '-' for standard input")

作为参考,使用信息将是

> 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
于 2012-07-30T12:37:21.597 回答