idiomatic analogue of Perl's: while (<>) { ... }
Peter Otten
__peter__ at web.de
Thu Sep 1 02:31:32 EDT 2011
Sahil Tandon wrote:
> I've been tasked with converting some programs from Perl -> Python, and
> am (as will soon be obvious) new to the language. A few archive/google
> searches were inconclusive on a consensus approach, which is OK, but I
> just wonder if there is a more Python-esque way to do the following in
> Python 2.7.1:
>
> %%
> # unbuffer STDOUT
> sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
>
> # process input, line-by-line, and print responses after parsing input
> while 1:
> rval = parse(raw_input())
> if rval == None:
> print('foo')
> else:
> print('bar')
> %%
>
> This works, but while reading the documentation, I thought of using 'for
> line in fileinput.input()' in lieu of 'while 1:' construct. This does
> not work when debugging the program on the command line -- the script
> appears to just hang no matter what is typed into STDIN. I believe this
> is because of some internal buffering when using fileinput. Is there a
> recommended way to disable such buffering? Am I taking a totally wrong
> approach?
>
> Feel free to just link me to previous discussions on the topic(s) if I
> have missed them. Please be gentle with your cluebats. :-)
A quick look into fileinput.py reveals that it uses readlines() and slurps
in the complete "file". I'm not sure that was a clever design decision...
Here's a partial reimplementation that should work for your use-case:
import sys
from itertools import chain
def _open_many(files):
for file in files:
if file == "-":
yield sys.stdin
else:
with open(file) as f:
yield f
def input(files=None, buffered=False):
if files is None:
files = sys.argv[1:]
if not files:
files = ["-"]
files = _open_many(files)
if not buffered:
files = (iter(file.readline, "") for file in files)
return chain.from_iterable(files)
for line in input():
print line.strip().upper()
More information about the Python-list
mailing list