(Multiple people on this thread have been quoting earlier people without keeping the attribution lines (e.g. xxxx yyy wrote: ) so I'm not sure who said what any more. I recognize my own words, of course, but for anybody else, your guess is
   better than mine)

Stephen Nelson-Smith wrote:
Evening,
Yes, you can, but not this way.  I'm guessing the op was changing his mind
back and forth, between having two files, one for reading and one for
writing, and trying to do it in place.  The code does neither/both.

Well, just neither I think!  I didn't check if 'rw' was possible.  My
plan was to read the file and write to the same file as the change was
made, to avoid having to use temporary files and os.move.  But I
wasn't near a machine with python on it, so it was untested.

The string to use is "r+b" The r says you're going to read it. The + says you're also going to write it. And the b says you don't want any character translation going on. Text files should only be written in one direction, or appended, but not updated in-place, except in very specific circumstances.

If you're both reading and writing, you need to do a seek() in between. So you'll be doing two seeks per loop. And since each line is a variable size, you'd have to keep track of that size. And if you were on a Windows machine, the size of the string you see may not match the size on the file ( 0d0a becomes 0a when reading a text file). Finally, even if you get all that right, the specific example is trying to replace lines with new lines of a different length. Not in this world.
Take a look at fileinput.FileInput()  with the inplace option.  It makes it
convenient to update text files "in place" by handling all the temp file
copying and such.  It even handles iterating through the list of files.

Will definitely look into that.

Good point about 'file' as its a built-in name.  If the code ever has to use
the std meaning, you have a problem.  Worse, it's unreadable as is.

Thanks for that hint.  In what way is it unreadable?  Because the
intent is not clear because of the ambiguity of the name?

Exactly. In that short fragment, there are three meanings for the name file. It's a built-in type until the first time you change it. Then it becomes a string. And after the with statement it becomes a file object. If you had to check its type, that would be quite difficult. And if you needed its name, you've clobbered it.

Also, you didn't define 'output' anywhere.  Is this an implicit
declaration

No, just a dumb mistake.

Another potential  bug with the code is if more than one "setting" could
appear in a line. It would change the line for an odd number, and not for an
even number of matches.

Not sure I follow that.  From the OPs description, it appeared he
would be entering these lines in.  I figured it was safe to trust the
OP not to put in duplicate data.  Maybe defensively I should check for
it anyway?

I'm not sure where these "settings" values come from. But if these are arbitrary command lines, it's plausible that one command works on a file whose name looks like one of the other commands. I'd feel better with something like "startswith()" instead of "in" . But just as a general precaution, I'd put a break in the for loop whenever one of them matches
Also, the nesting of output.write() is wrong, because file position isn't
preserved, and random access in a text file isn't a good idea anyway.

Could you expand on this?

As it stands, it only writes the line when it needs to change. But that implies that you've been keeping track of sizes so you can put a seek before and after the line, and of course that the size doesn't change. Since none of these is true (or practical), my comment was assuming that you're using a different "output" file. So you need to write every line, not just the ones that change.
 But
there's not much point in debugging that till the OP decides how he's going
to handle the updates, via new files and copying or renaming, or via
inputfile.

I'll look up inputfile, and try again :)

S.


With inputfile, you'll basically copy the file from the supplied iterator to stdout (probably using print), doing any conversions on the line as you go.

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

Reply via email to