Discussion:
[Tutor] More Pythonic?
richard kappler
2015-09-09 13:05:23 UTC
Permalink
Would either or both of these work, if both, which is the better or more
Pythonic way to do it, and why?

#######################

import whatIsNeeded

writefile = open("writefile", 'a')

with open(readfile, 'r') as f:
for line in f:
if keyword in line:
do stuff
f1.write(line)
else:
f1.write(line)

writefile.close()

######################

import whatIsNeeded

with open(readfile, 'r') as f:
for line in f:
try:
if keyword in line:
do stuff
except:
do nothing
with open(writefile, 'a') as f1:
f1.write(line)

######################

or something else altogether?

I'm thinking the first way is better as it only opens the files once
whereas it seems to me the second script would open and close the writefile
once per iteration, and the do nothing in the except seems just wrong to
me. Is my thinking on target here?

regards, Richard
--
All internal models of the world are approximate. ~ Sebastian Thrun
_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor
Peter Otten
2015-09-09 13:37:37 UTC
Permalink
Post by richard kappler
Would either or both of these work, if both, which is the better or more
Pythonic way to do it, and why?
#######################
import whatIsNeeded
writefile = open("writefile", 'a')
do stuff
f1.write(line)
f1.write(line)
Why do you invoke f1.write() twice?
Post by richard kappler
writefile.close()
######################
import whatIsNeeded
do stuff
What exceptions are you expecting here? Be explicit. You probably don't want
to swallow a KeyboardInterrupt. And if something unexpected goes wrong a
noisy complaint gives you the chance to either fix an underlying bug or
explicitly handle the exception in future runs of the script.
Post by richard kappler
do nothing
That's spelt
pass
Post by richard kappler
f1.write(line)
Opening the file once per line written seems over-the-top to me.
Post by richard kappler
######################
or something else altogether?
I tend to put the processing into into a generator. That makes it easy to
replace the source or the consumer:

def process_lines(instream):
for line in instream:
if keyword in line:
do stuff
yield line

with open(sourcefile) as instream:
with open(destfile, "a") as outstream:
outstream.writelines(process_lines(instream))

Now if you want to read from stdin and print to stdout:

sys.stdout.writelines(process_lines(sys.stdin))
Post by richard kappler
I'm thinking the first way is better as it only opens the files once
whereas it seems to me the second script would open and close the
writefile once per iteration, and the do nothing in the except seems just
wrong to me.
It's not clear why you need the try...except: pass.
Please provide some more background information.


_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor
richard kappler
2015-09-09 13:47:04 UTC
Permalink
It's not clear why you need the try...except: pass. Please provide some
more background information.

I don't need the try, this was more of a "are there different ways to do
this, which is better and why?" experiment. I am learning, so tend to write
script that is more brute force than elegant and pythonic, wish to write
better code. I do okay, but there are many nuances to Python that I just
outstream.writelines(process_lines(instream))
I had no idea I could nest with statements like that. It seems obvious now,
but I didn't know.

For the record, I have made a couple other posts this morning that explain
the script constraints far better than I did here. For the sake of brevity
I shant repeat the info here other than to say it's not reading from stdin,
but from a log file to simulate stdin in a test environment.

regards, Richard
Post by richard kappler
Would either or both of these work, if both, which is the better or more
Pythonic way to do it, and why?
#######################
import whatIsNeeded
writefile = open("writefile", 'a')
do stuff
f1.write(line)
f1.write(line)
Why do you invoke f1.write() twice?
Post by richard kappler
writefile.close()
######################
import whatIsNeeded
do stuff
What exceptions are you expecting here? Be explicit. You probably don't want
to swallow a KeyboardInterrupt. And if something unexpected goes wrong a
noisy complaint gives you the chance to either fix an underlying bug or
explicitly handle the exception in future runs of the script.
Post by richard kappler
do nothing
That's spelt
pass
Post by richard kappler
f1.write(line)
Opening the file once per line written seems over-the-top to me.
Post by richard kappler
######################
or something else altogether?
I tend to put the processing into into a generator. That makes it easy to
do stuff
yield line
outstream.writelines(process_lines(instream))
sys.stdout.writelines(process_lines(sys.stdin))
Post by richard kappler
I'm thinking the first way is better as it only opens the files once
whereas it seems to me the second script would open and close the
writefile once per iteration, and the do nothing in the except seems just
wrong to me.
It's not clear why you need the try...except: pass.
Please provide some more background information.
_______________________________________________
https://mail.python.org/mailman/listinfo/tutor
--
All internal models of the world are approximate. ~ Sebastian Thrun
_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor
Steven D'Aprano
2015-09-09 13:41:08 UTC
Permalink
Post by richard kappler
Would either or both of these work, if both, which is the better or more
Pythonic way to do it, and why?
#######################
import whatIsNeeded
writefile = open("writefile", 'a')
do stuff
f1.write(line)
f1.write(line)
writefile.close()
######################
Better would be this:

with open("writefile", 'a') as outfile:
with open("readfile", 'r') as infile:
for line in infile:
if keyword in line:
do stuff
outfile.write(line)

(I think your intention is to always write the lines into the output
file, but there are enough typos in your version that I can't be
completely sure.)
Post by richard kappler
import whatIsNeeded
do stuff
do nothing
Why are you ignoring *all errors*? That will make it impossible (or at
least very hard) to cancel the script with Ctrl-C, and it will cover
up programming errors. Apart from a very few expert uses, you should
never use a bare except. If you really want to "ignore all errors", use
`except Exception`, but even that is not good practice. You should list
and catch only the precise errors that you know you wish to ignore and
can safely handle. Everything else indicates a bug that needs fixing.

By the way, "do nothing" in Python is spelled "pass".
Post by richard kappler
f1.write(line)
And this will repeatedly open the file, append one line, then close it
again. Almost certainly not what you want -- it's wasteful and
potentially expensive.
Post by richard kappler
######################
or something else altogether?
I'm thinking the first way is better as it only opens the files once
whereas it seems to me the second script would open and close the writefile
once per iteration, and the do nothing in the except seems just wrong to
me. Is my thinking on target here?
Spot on target.
--
Steve
_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor
Timo
2015-09-09 18:36:17 UTC
Permalink
Post by richard kappler
Post by richard kappler
Would either or both of these work, if both, which is the better or more
Pythonic way to do it, and why?
#######################
import whatIsNeeded
writefile = open("writefile", 'a')
do stuff
f1.write(line)
f1.write(line)
writefile.close()
######################
do stuff
outfile.write(line)
It's also possible to use multiple with statements on the same line. Can
someone with more expert Python knowledge than me comment on whether
it's different from using them separate as mentioned by Steven?

This is what I had in mind:

with open("writefile", 'a') as outfile, open("readfile", 'r') as infile:
pass # Rest of the code here


Timo


_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor
Peter Otten
2015-09-09 18:59:42 UTC
Permalink
Post by Timo
Post by richard kappler
Post by richard kappler
Would either or both of these work, if both, which is the better or more
Pythonic way to do it, and why?
#######################
import whatIsNeeded
writefile = open("writefile", 'a')
do stuff
f1.write(line)
f1.write(line)
writefile.close()
######################
do stuff
outfile.write(line)
It's also possible to use multiple with statements on the same line. Can
someone with more expert Python knowledge than me comment on whether
it's different from using them separate as mentioned by Steven?
pass # Rest of the code here
This requires Python 2.7 or higher. Other than that the choice is merely a
matter of taste. Both versions even produce the same bytecode:

$ cat nested_with.py
def f():
with open("writefile", 'a') as outfile, open("readfile", 'r') as infile:
pass # Rest of the code here

def g():
with open("writefile", 'a') as outfile:
with open("readfile", 'r') as infile:
pass # Rest of the code here

print(f.__code__.co_code == g.__code__.co_code)
$ python nested_with.py
True

Personally I find one item per with statement more readable and don't care
about the extra indentation level.

_______________________________________________
Tutor maillist - ***@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor

Continue reading on narkive:
Loading...