Argparse optional stdin argument

I am trying to specify an optional argument that stdin takes. This will be mainly used for data transfer in my program, therefore someprog that outputs | python my_prog.

I followed the argparse documentation and I read a lot of questions / answers about this in Stackoverflow, but none of them seem to work for me.

Here is what I originally had:

parser = argparse.ArgumentParser(description='Upgrade Instance.')
parser.add_argument('--app', '-a', dest='app', action='store', required=True)
parser.add_argument('--version', '-v', dest='version', action='store', default='', required=False)
parser.add_argument('--config', '-c', dest='config', action='store', default = '', required=False)
args = parser.parse_args()

Now what I want to do is let the user go through versionwith the channel, rather than transmit it.

I added parser.add_argument('infile', nargs='?', type=argparse.FileType('r'), default=sys.stdin)to the beginning, but that makes it a positional argument. How is this possible? I thought that nargs=?made it optional.

I need this to be an optional argument. So I changed it to:

parser.add_argument('--infile', nargs='?', type=argparse.FileType('r'), default=sys.stdin)

, stdin, , . default=sys.stdin - , :

close failed in file object destructor:
sys.excepthook is missing
lost sys.stderr

. args, : Namespace(app='app', config='', g=False, hosts='03.app', infile=None, version='').

, , . , , .

, ?

+4
3

... . , , . raw_input() .

import sys

if not sys.stdin.isatty():
    stdin = sys.stdin.readlines()
    print stdin
    sys.stdin = open('/dev/tty')
else:
    print "No stdin"

test_raw = raw_input()
print test_raw

-

rypeck$ echo "stdin input" | python test_argparse.py -a test 
['stdin input\n']
raw_input working!
raw_input working!
rypeck$ python test_argparse.py -a test
No stdin
raw_input working!
raw_input working!
+3

, , . 100% , stdin, , , , ; . 3,4, ...

, :

parser.add_argument("-v", "--version", nargs='?', const=sys.stdin, action=StreamType)

, , , , , . StreamType - argparse.Action, , stdin , :

class StreamType(argparse.Action):
    def __call__(self, parser, namespace, values, option_string=None):
        try:
            setattr(namespace, self.dest, values.readline().strip())
        except AttributeError:
            setattr(namespace, self.dest, values)

- :

$ blah --version v1.1.1
Namespace(version='v1.1.1')

$ echo "v1.0.3" | blah --version
Namespace(version='v1.0.3')
+3

args.infile? , argparse , .

p = argparse.ArgumentParser()
p.add_argument('--infile', type=argparse.FileType('r'),default='-')
# p.add_argument('infile', nargs='?', type=argparse.FileType('r'),default='-') # positional version
args = p.parse_args()
print(args)
print args.infile.read()
-----------
$ cat myprog.py | python myprog.py --infile -
$ cat myprog.py | python myprog.py
$ python myprog.py myprog.py  # with the positional version
$ python myprog.py - < myprog.py  # with the positional version

. " ".

, optional/positional optional/required.

(, "positional" ) , - --, optional. required False, True. 'infile' ( ), positional, ? is optional ( ).

, action 'store', . required, True.

Using a FileTypeconvenient way to indicate stdin- -.

Do not use '?'with --infileif you really do not wantNone

+2
source

All Articles