【问题标题】:A substite for "for looping" in text files替代文本文件中的“for循环”
【发布时间】:2013-03-19 20:38:49
【问题描述】:
from unidecode import *
reader = open("a.txt",'w')
def unite():
    for line in reader:
        line = unidecode(line)
        print (line)
unite()

现在,我收到一条错误消息,指出在写入模式下不允许循环。有没有其他方法,我可以像这样修改每一行,以便可以使用 unidecode 进行转换?

【问题讨论】:

  • 读取所有行,修改然后写回。 AFAIK 你不能像那样修改行。
  • 阅读时如何编辑文件?
  • @madprogramer 你不能同时读写。考虑打开另一个文件进行编辑。
  • 您可以使用较低级别的 OS API 同时读取和写入,但只有在内容大小相同时才有用(通常 unicode 文本比“unidecoded”ascii 长)。

标签: python for-loop filewriter file-read unidecoder


【解决方案1】:

你可以把它全部记住。

from unidecode import *

reader = open("a.txt",'w')
lines = reader.readlines()
def unite(lines):
    for line in lines:
        line = unidecode(line)
        print (line)
unite()

您也可以使用临时文件。

from unidecode import *
import os

reader = open('a.txt','r')
temp = open('~a.txt', 'w')
for line in reader():
    line = unidecode(line)
    temp.write(line)
reader.close()
temp.close()

os.remove('a.txt')
os.rename('~a.txt', 'a.txt')

【讨论】:

  • for line in reader 就足够了 - 取决于 python 版本,readlines() 会将整个文件存储在内存中。这对于小文件来说很好,但对于大文件来说可能会耗尽所有内存。
【解决方案2】:

这是一个有点肮脏的秘密,但很少有应用程序能够真正“就地”更改文件。大多数情况下,看起来应用程序正在修改文件,但在后台,编辑后的文件被写入临时位置,然后移动到替换原来的位置。

如果你考虑一下,当你在文件中间插入几个字节时,无论如何你必须从这一点重写整个文件。

由于 ascii 输出往往比 unicode 输入小,您可能可以完成类似这样的操作(我猜只有 unix):

    #!/usr/bin/env python
    import os
    from unidecode import unidecode

    def unidecode_file(filename):
        # open for write without truncating
        fd = os.open(filename, os.O_WRONLY) 
        pos = 0 # keep track of file length
        # open for read
        with open(filename) as input:
            for line in input:
                ascii = unidecode(line.decode('utf-8'))
                pos += len(ascii)
                os.write(fd, ascii)
        os.ftruncate(fd, pos) # truncate output
        os.close(fd) # that is all, folks

    if __name__ == '__main__':
        unidecode_file('somefile.txt')

这个特技是不安全的,也不是编辑文件的规范方法(如果输出大于输入,你肯定会遇到麻烦)。使用Drew 建议的临时文件方法,但要确保文件名的唯一性(最安全的方法是为临时文件生成随机文件名)。

【讨论】:

    【解决方案3】:

    您可以在附加模式下打开它:

    def unite():
        with open('somefile.txt','a+') as f:
            for line in f:
                f.write(unidecode(line))
                print line
    
    unite()
    

    这会将内容写入文件末尾。要从文件开头写入内容,请使用模式r+

    例如:

    sample.txt:

    hello world
    

    当你运行这个时:

    with open('sample.txt','a+') as f:
        line = f.readline()
        f.write('{} + again'.format(line.strip()))
    

    该文件将具有:

    hello world
    hello world again
    

    如果你运行:

    with open('sample.txt','r+') as f:
        line = f.readline()
        f.write('{} + once more'.format(line.strip()))
    

    该文件将具有:

    hello world
    hello world once more
    hello world again
    

    如果你想替换文件的内容,那么你可以读取文件,保存行,关闭它并以写模式打开它来写回这些行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-12
      相关资源
      最近更新 更多