Python Read from Stdin with Arguments

前端 未结 1 1601
不知归路
不知归路 2021-01-07 02:30

I want to read from python stdin but also to have input options in my program. When I try to pass an option to my programm I get the error file not found and my arguments ar

相关标签:
1条回答
  • 2021-01-07 03:24

    Your preprocess.py file is trying to read form sys.argv[1] and open it as a file.

    If you pass -h to your command line, it is trying to open file with that name.

    split command line parsing from processing

    Your preprocess function shall not care about command line parameters, it shall get the open file descriptor as an argument.

    So after you parse command line parameters, you shall take care about providing file descriptor, in your case it will be sys.stdin.

    Sample solution using docopt

    There is nothing wrong with argparse, my favourite parser is docopt and I will use it to illustrate typical split of command line parsing, preparing final function call and final function call. You can achieve the same with argparse too.

    First install docopt:

    $ pip install docopt
    

    Here comes the fromstdin.py code:

    """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)
    

    Can be called like:

    $ python fromstdin.py
    Usage: fromstdin.py [options] <input>
    

    Show the help:

    $ 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.
    

    Use it, feeding 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
    
    0 讨论(0)
提交回复
热议问题