我必须用这个命令行编写一个程序:
demo.py [-h] -f FILENAME [-o]
文件名是必需的,表示我们要追加的文件。 -o标志表示文件将被覆盖。
这个argparse代码几乎可以工作:
import argparse
parser = argparse.ArgumentParser(description='A foo that bars')
parser.add_argument("-f",
"--file", dest="filename", required=True,
type=argparse.FileType('a+'),
help="The output file (append mode, see --overwrite).")
parser.add_argument("-o",
"--overwrite", dest="overwrite",
action='store_true',
help="Will overwrite the filename if it exists")
args = parser.parse_args()
if args.overwrite:
args.filename.truncate(0)
print >> args.filename, 'Hello, World!'
但如果我将-
(stdout)指定为文件名,我会收到此错误:
error: argument -f/--file: invalid FileType('a+') value: '-'
我尝试了a
或r+
,我得到了同样的错误。我在Windows上使用Python 2.7,但它也必须在Linux上运行。对于旧版支持,命令行无法更改。
如何保持argparse
内置支持stdout简写,但支持覆盖功能?
答案 0 :(得分:4)
argparse.FileType.__call__
包含以下代码:
if string == '-':
if 'r' in self._mode:
return _sys.stdin
elif 'w' in self._mode:
return _sys.stdout
else:
msg = _('argument "-" with mode %r') % self._mode
raise ValueError(msg)
因此,如果self._mode
为'a+'
,则Python会引发ValueError。
你可以通过继承argparse.FileType
:
import argparse
import sys as _sys
class MyFileType(argparse.FileType):
def __call__(self, string):
# the special argument "-" means sys.std{in,out}
if string == '-':
if 'r' in self._mode:
return _sys.stdin
elif any(m in self._mode for m in 'wa'):
return _sys.stdout
else:
msg = _('argument "-" with mode %r') % self._mode
raise ValueError(msg)
# all other arguments are used as file names
try:
return open(string, self._mode, self._bufsize)
except IOError as e:
message = _("can't open '%s': %s")
raise ArgumentTypeError(message % (string, e))
def parse_options():
parser = argparse.ArgumentParser(description='A foo that bars')
parser.add_argument("-f",
"--file", dest="filename", required=True,
type=MyFileType('a+'),
help="The output file (append mode, see --overwrite).")
parser.add_argument("-o",
"--overwrite", dest="overwrite",
action='store_true',
help="Will overwrite the filename if it exists")
args = parser.parse_args()
if args.overwrite:
args.filename.truncate(0)
return args
args = parse_options()
print >> args.filename, 'Hello, World!'