[Tutor] proxy switcher - was Re: I love python / you guys :)
davea at ieee.org
Mon Nov 16 20:56:15 CET 2009
(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:
>> 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
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
> 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.
>> 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
> I'll look up inputfile, and try again :)
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.
More information about the Tutor