首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >io.UnsupportedOperation:不可读

io.UnsupportedOperation:不可读
EN

Stack Overflow用户
提问于 2012-11-14 07:05:08
回答 1查看 38.2K关注 0票数 4

我正在解决一个问题,即编写一个程序,获取用户对文件的输入,然后在文件中删除用户指定的字符串。我不确定如何从我所拥有的(下面)到问题所要求的。我们将一如既往地感谢您的帮助。

代码语言:javascript
复制
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()

我采纳了其中一个建议,并尝试让它工作,但正如我在下面的注释中所说的那样,下面的代码没有返回错误,它创建了一个空文件。要使新文件成为删除了字符串的旧文件,我会遗漏什么?

代码语言:javascript
复制
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()
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-11-14 07:17:16

在进入细节之前有几个附注:当您调用string.replace(string, "")时,您是在告诉string用空字符串替换它的整个自身--您可能只需要执行string = ""。假设第一个string是要替换的搜索字符串,因此请给它一个不同的名称,然后将其用作例如string.replace(searchString, "")。此外,您不希望将变量命名为string,因为它是标准库模块的名称。您将输入文件称为"outfile",这很容易混淆。您可能希望使用with语句,而不是显式的close。最后,您只需使用for line in f:就可以迭代文件中的行;您不需要for line in f.readlines() (而且,如果您需要处理Python2.x,您会更乐意避免使用readlines(),因为它会将整个文件读取到内存中,然后在内存中生成一个巨大的行列表)。

正如JBernardo所指出的,第一个问题是你已经在"a“模式下打开了文件,这意味着”只写,附加到最后“。如果你想读写,你可以使用"a+“或"r+”。

然而,这并不能真正帮助到你。毕竟,您不能在读取文件的过程中对其进行写入。

有几种常见的方法来解决这个问题。

首先,只需写入标准输出,并让用户随心所欲地处理结果-例如,将其重定向到文件。(在这种情况下,您已经将提示符、“完成”消息等输出到标准错误,这样它们就不会被重定向到该文件。)这是许多Unix工具(如sedsort )所做的,所以如果您正在构建Unix风格的工具,那么它是合适的,但可能不适合用于其他目的。

代码语言:javascript
复制
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")

第二,写入另一个文件。以"r“模式打开输入文件,以"w”模式打开输出文件,然后您只需复制行:

代码语言:javascript
复制
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")

第三,读取并处理内存中的整个文件,然后截断并重写整个文件:

代码语言:javascript
复制
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)

最后,写入一个临时文件(与第二个选项一样),然后将该临时文件移动到原始输入文件的顶部。如下所示:

代码语言:javascript
复制
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)

最后一个有点棘手,因为POSIX和Windows之间存在差异。然而,它也有一些很大的优势。(例如,如果您的程序在运行过程中被终止,无论它是如何发生的,您都可以保证拥有原始文件或新文件,而不是一些半途而废的混乱。)

票数 9
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13370428

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档