Python 文件作为argparse的命令行参数-参数无效时显示错误消息
我目前使用的argparse如下所示:Python 文件作为argparse的命令行参数-参数无效时显示错误消息,python,argparse,Python,Argparse,我目前使用的argparse如下所示: import argparse from argparse import ArgumentParser parser = ArgumentParser(description="ikjMatrix multiplication") parser.add_argument("-i", dest="filename", required=True, help="input file with two matrices", metavar="FILE"
import argparse
from argparse import ArgumentParser
parser = ArgumentParser(description="ikjMatrix multiplication")
parser.add_argument("-i", dest="filename", required=True,
help="input file with two matrices", metavar="FILE")
args = parser.parse_args()
A, B = read(args.filename)
C = ikjMatrixProduct(A, B)
printMatrix(C)
现在我想指出,-I
的参数应该是一个可读文件。我该怎么做
我已尝试添加
type=open
,type=argparse.FileType('r')
,它们都有效,但如果文件无效,我希望得到一条错误消息。我该怎么做呢?其实很简单。您只需要编写一个函数来检查文件是否有效,否则会写入一个错误。将该功能与类型
选项一起使用。请注意,您可以通过子类化argparse.action
来创建一个自定义操作,但我认为在这里没有必要这样做。在我的示例中,我返回一个打开的文件句柄(请参见下文):
我刚刚找到了这个:
def extant_file(x):
"""
'Type' for argparse - checks that file exists but does not open.
"""
if not os.path.exists(x):
# Argparse uses the ArgumentTypeError to give a rejection message like:
# error: argument input: x does not exist
raise argparse.ArgumentTypeError("{0} does not exist".format(x))
return x
if __name__ == "__main__":
import argparse, sys, os
from argparse import ArgumentParser
parser = ArgumentParser(description="ikjMatrix multiplication")
parser.add_argument("-i", "--input",
dest="filename", required=True, type=extant_file,
help="input file with two matrices", metavar="FILE")
args = parser.parse_args()
A, B = read(args.filename)
C = ikjMatrixProduct(A, B)
printMatrix(C, args.output)
来源:在Python3.4中实现这一点的方法是使用类。确保完成后关闭输入流。这也很有用,因为可以对STDIN/STDOUT使用伪参数
'-'
。从文件中:
FileType对象理解伪参数'-'
,并自动将其转换为可读对象的sys.stdin
,以及可写对象的sys.stdout
例如:
#!/usr/bin/env python3
import argparse
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('--infile', type=argparse.FileType('r', encoding='UTF-8'),
required=True)
args = parser.parse_args()
print(args)
args.infile.close()
然后当我跑的时候
- 毫无争议:
$ ./stack_overflow.py usage: stack_overflow.py [-h] --infile INFILE stack_overflow.py: error: the following arguments are required: --infile
- 对于不存在的文件:
$ ./stack_overflow.py --infile notme usage: stack_overflow.py [-h] --infile INFILE stack_overflow.py: error: argument --infile: can't open 'notme': [Errno 2] No such file or directory: 'notme'
- 使用现有文件:
$ ./stack_overflow.py --infile ./stack_overflow.py Namespace(infile=<_io.TextIOWrapper name='./stack_overflow.py' mode='r' encoding='UTF-8'>)
os.path.isfile
可能比os.path.exists
(取决于您是否也要接受目录)更合适。事实上,与检查existence@jarondl这是对的。这应该更改为使用try:。。。IOError除外
,以避免潜在的竞争条件。在大多数情况下,这并不重要,但最近这让我感到痛苦。提高argparse.ArgumentTypeError
会使代码更简洁。(正如moose的回答中所指出的那样)你不必尝试打开文件,因为打开
将自行处理所有错误情况。然后,您可能会在except
子句中发现这一点,但我认为这种情况下不需要它。argparse.FileType
在Python 2.7中也可用。如果对不同的输入参数有多个argparse.FileType
用法,并且它们都使用-
?@cmcdragokai,从文档中可以看到:如果sys.stdin被多次使用,第二次和以后的使用将不会返回任何行,除了交互使用,或者如果它已被显式重置(例如使用sys.stdin.seek(0))
$ ./stack_overflow.py --infile ./stack_overflow.py
Namespace(infile=<_io.TextIOWrapper name='./stack_overflow.py' mode='r' encoding='UTF-8'>)
$ echo 'hello' | ./stack_overflow.py --infile -
Namespace(infile=<_io.TextIOWrapper name='<stdin>' mode='r' encoding='UTF-8'>)