12

When writing text-oriented command line programs in Python, I often want to read either all the files passed on the command line, or (XOR) standard input (like Unix cat does, or Perl's <>). So, I say

if len(args) == 0:  # result from optparse
    input = sys.stdin
else:
    input = itertools.chain(*(open(a) for a in args))

Is this the Pythonic way of doing this, or did my miss some part of the library?

Marc Mutz - mmutz
  • 24,485
  • 12
  • 80
  • 90
Fred Foo
  • 355,277
  • 75
  • 744
  • 836
  • See https://stackoverflow.com/questions/1450393/how-do-you-read-from-stdin-in-python –  Apr 15 '11 at 11:25
  • It's definitely worth following this link if you need more in-depth responses. There's a caveat for Python 2, for example. – Michael Scheper Jun 06 '14 at 23:30

2 Answers2

15

You need fileinput.

A standard use case is:

import fileinput
for line in fileinput.input():
  process(line)
Richard
  • 56,349
  • 34
  • 180
  • 251
eumiro
  • 207,213
  • 34
  • 299
  • 261
  • 1
    This is fine if you want to read the file line by line, but if you just want the whole contents of the file in a variable (the equivalent of `open("", 'r').read()`) there is no built-in way to do that with the `fileinput` stdlib module. Unless I'm mistaken in reading the docs. – tehwalrus May 25 '17 at 08:25
  • @tehwalrus I worked around that with `allText=""` before the for loop, and `allText += line` in it. – AstroFloyd May 21 '20 at 13:01
  • You're right about the absence of a `read()` method. However, for concatenating lines, adding up lines is officially not recommended. It is much more efficient to collect them in a list and then joining them with `"".join(lines)`—this is the officially recommended method. – Eric O. Lebigot Mar 08 '21 at 16:49
2

In Python 3, argparse handles filetype objects very nicely. It's an extremely powerful module and the docs come with many examples, so it's easy to quickly write the code you want. (How Pythonic!)

You may also benefit from this StackOverflow question about using argparse to optionally read from stdin.

Community
  • 1
  • 1
Michael Scheper
  • 6,514
  • 7
  • 63
  • 76