Io.UsupportedOperation: not readable

I am working on a problem that says to make a program that receives user input for a file and then in the file deletes the line that the user indicates. I do not know how to go from what I have (below) to what is asking the question. As always, any help is appreciated.

def main(): outfile = open(input("Enter a file name: "), "a") string = input("Enter the string to be removed: ") for string in outfile.readlines(): string = string.replace(string, "") outfile.close() print("Done") main() 

I accepted one of the suggestions and tried to make it work, but, as I said in my comment below, the code below does not return an error, it creates an empty file. What am I missing to get a new file as an old file with a deleted line?

 def main(): inpath = input("Enter an input file: ") line = input("Enter what you want to remove: ") outpath = input("Enter an output file: ") with open(inpath, "r") as infile, open(outpath, "w") as outfile: for line in infile: outfile.write(line.replace(line, "") + "\n") print("Done.") main() 
+4
source share
1 answer

A few notes on the details before entering the details: when you call string.replace(string, "") , you say that the string replaced all its selves with an empty string - you could just do string = "" . Presumably, the first string is the search string you are looking for, so give it a different name and then use it like, for example, string.replace(searchString, "") . In addition, you do not want to name the variable string , because this is the name of a standard library module. You call your input file "outfile", which can be misleading. You probably want to use the with statement instead of explicitly closing it. Finally, you can iterate through lines in a file only with for line in f: you do not need for line in f.readlines() (and if you ever need to work with Python 2.x, you will be much happier to avoid readlines() because it will read the entire file in memory and then make a huge list lines in memory).

The first problem, as JBernardo pointed out, is that you opened the file in "a" mode, which means "write-only, append to the end". You can use "a +" or "r +" if you want to read and write.

However, this will not help you. After all, you cannot write a file in the middle of reading.

There are several common ways.

First, just write to standard output and let the user do whatever he wants with the results, for example, redirect it to a file. (In this case, you print your message instead, the message β€œFinish”, etc.), so they are not redirected to the file.) This is what many Unix tools, such as sed or sort , do, so this is necessary, if you are creating a style tool in a Unix style, but might be wrong for other purposes.

 def stderrinput(prompt): sys.stderr.write(prompt) sys.stderr.flush() return input() def main(): with open(stderrinput("Enter a file name: "), "r") as infile: searchString = stderrinput("Enter the string to be removed: ") for line in infile: print(infile.replace(searchString, "")) sys.stderr.write("Done\n") 

Secondly, write to another file. Open the input file in "r" mode and the output file in "w" mode, and then you simply copy the lines:

 def main(): inpath = input("Enter an input file: ") outpath = input("Enter an output file: ") with open(inpath, "r") as infile, open("outpath", "w") as outfile: for line in infile: outfile.write(line.replace(searchString, "") + "\n") 

Third, read and process the entire file in memory, then crop and rewrite the entire file:

 def main(): path = input("Enter an input/output file: ") with open(path, "r+") as inoutfile: lines = [line.replace(searchString, "") for line in inoutfile] inoutfile.seek(0) inoutfile.truncate() inoutfile.writelines(lines) 

Finally, write to a temporary file (like the second option), and then move this temporary file over the original input file. Something like that:

 def main(): path = input("Enter an input/output file: ") with open(path, "r") as infile, tempfile.NamedTemporaryFile("w", delete=False) as outfile: for line in infile: outfile.write(line.replace(searchString, "")) shutil.move(outfile.name, pathname) 

This last one is a bit complicated, due to the differences between POSIX and Windows. However, this has some great advantages. (For example, if your program is killed in the middle of the operation, no matter how it happens, you are guaranteed to have either the original file or a new file, and not some kind of semi-recorded mess.)

+8
source

Source: https://habr.com/ru/post/1445890/


All Articles