Python 从标准输入读取参数
我想从Python的标准输入读取数据,但同时我的程序也需要有输入选项。当我尝试给我的程序传递一个选项时,出现了“找不到文件”的错误,导致我的参数被忽略了。
为了处理这些参数,我使用了以下代码:
parser=argparse.ArgumentParser(description='Training and Testing Framework')
parser.add_argument('--text', dest='text',
help='The text model',required=True)
parser.add_argument('--features', dest='features',
help='The features model',required=True)
parser.add_argument('--test', dest='testingset',
help='The testing set.',required=True)
parser.add_argument('--vectorizer', dest='vectorizer',
help='The vectorizer.',required=True)
args = vars(parser.parse_args())
为了从标准输入读取数据,我使用了以下代码:
for line in sys.stdin.readlines():
print(preprocess(line,1))
命令行
echo "dsfdsF" |python ensemble.py -h
/usr/local/lib/python2.7/dist-packages/pandas/io/excel.py:626: UserWarning: Installed openpyxl is not supported at this time. Use >=1.6.1 and <2.0.0.
.format(openpyxl_compat.start_ver, openpyxl_compat.stop_ver))
Traceback (most recent call last):
File "ensemble.py", line 38, in <module>
from preprocess import preprocess
File "/home/nikos/experiments/mentions/datasets/preprocess.py", line 7, in <module>
with open(sys.argv[1], 'rb') as csvfile:
IOError: [Errno 2] No such file or directory: '-h'
1 个回答
5
你的 preprocess.py
文件正在尝试读取 sys.argv[1]
,并把它当作一个文件来打开。
如果你在命令行中输入 -h
,它会试图用这个名字去打开一个文件。
将命令行解析和处理分开
你的 preprocess
函数不应该关心命令行参数,它应该把打开的文件描述符作为一个参数传入。
所以在你解析完命令行参数后,你需要提供文件描述符,在你的情况下,这个文件描述符将是 sys.stdin
。
使用 docopt
的示例解决方案
使用 argparse 没有什么问题,我最喜欢的解析器是 docopt
,我将用它来展示如何典型地分开命令行解析、准备最终的函数调用和最终的函数调用。你也可以用 argparse 达到同样的效果。
首先安装 docopt:
$ pip install docopt
接下来是 fromstdin.py
的代码:
"""fromstdin - Training and Testing Framework
Usage: fromstdin.py [options] <input>
Options:
--text=<textmodel> Text model [default: text.txt]
--features=<features> Features model [default: features.txt]
--test=<testset> Testing set [default: testset.txt]
--vectorizer=<vectorizer> The vectorizec [default: vector.txt]
Read data from <input> file. Use "-" for reading from stdin.
"""
import sys
def main(fname, text, features, test, vectorizer):
if fname == "-":
f = sys.stdin
else:
f = open(fname)
process(f, text, features, test, vectorizer)
print "main func done"
def process(f, text, features, test, vectorizer):
print "processing"
print "input parameters", text, features, test, vectorizer
print "reading input stream"
for line in f:
print line.strip("\n")
print "processing done"
if __name__ == "__main__":
from docopt import docopt
args = docopt(__doc__)
print args
infile = args["<input>"]
textfile = args["--text"]
featuresfile = args["--features"]
testfile = args["--test"]
vectorizer = args["--vectorizer"]
main(infile, textfile, featuresfile, testfile, vectorizer)
可以这样调用:
$ python fromstdin.py
Usage: fromstdin.py [options] <input>
显示帮助信息:
$ python fromstdin.py -h
fromstdin - Training and Testing Framework
Usage: fromstdin.py [options] <input>
Options:
--text=<textmodel> Text model [default: text.txt]
--features=<features> Features model [default: features.txt]
--test=<testset> Testing set [default: testset.txt]
--vectorizer=<vectorizer> The vectorizec [default: vector.txt]
Read data from <input> file. Use "-" for reading from stdin.
使用它,从标准输入获取数据:
(so)javl@zen:~/sandbox/so/cmd$ ls | python fromstdin.py -
{'--features': 'features.txt',
'--test': 'testset.txt',
'--text': 'text.txt',
'--vectorizer': 'vector.txt',
'<input>': '-'}
processing
input parameters text.txt features.txt testset.txt vector.txt
reading input stream
bcmd.py
callit.py
fromstdin.py
scrmodule.py
processing done
main func done