【问题标题】:Preserve end-of-line style when working with files in python在 python 中处理文件时保留行尾样式
【发布时间】:2011-02-28 16:05:24
【问题描述】:

我正在寻找一种方法来确保在 python 程序中读取、编辑和写入时保持文件的行尾样式。

Python 具有通用文件结尾支持,可以在读取文件时将所有行结尾转换为\n,然后在写入文件时将它们全部转换为系统默认值。在我的情况下,我仍想进行初始转换,但随后使用原始 EOL 样式而不是系统默认样式编写文件。

有没有标准的方法来做这种事情?如果没有,是否有检测文件 EOL 样式的标准方法?

假设没有标准的方法来做到这一点,一个可能的工作流程是:

  1. 以二进制模式读入文件。
  2. 解码为 utf-8(或任何需要的编码)。
  3. 检测 EOL 样式。
  4. 将所有行尾转换为\n

  5. 处理文件。

  6. 将所有行尾转换为原始样式。

  7. 编码文件。
  8. 以二进制模式写入文件。

在此工作流程中,执行第 2 步的最佳方法是什么?

【问题讨论】:

    标签: python line-endings


    【解决方案1】:

    要保留原始行尾,请使用newline='' 读取或写入未翻译的行尾。

    with open('test.txt','r',newline='') as rf:
        content = rf.read()
    content = content.replace('old text','new text')
    with open('testnew.txt','w',newline='') as wf:
        wf.write(content)
    

    请注意,如果文本操作本身处理行尾,则可能需要额外或替代逻辑来检测和匹配原始行尾。

    'U' 模式也可以使用,但已弃用。

    Python Documentation: open

    换行控制通用换行模式的工作方式(它仅适用于文本模式)。它可以是None'''\n''\r''\r\n'。它的工作原理如下:

    • 从流中读取输入时,如果换行符为无,则启用通用换行符模式。输入中的行可以以'\n''\r''\r\n' 结尾,这些行在返回给调用者之前会被翻译成'\n'如果是'',则启用通用换行模式,但行尾不翻译返回给调用者。如果它具有任何其他合法值,则输入行仅由给定字符串终止,并且行尾未翻译地返回给调用者。

    • 将输出写入流时,如果换行符为None,则写入的任何'\n' 字符都将转换为系统默认行分隔符os.linesep如果换行符是'''\n',则不会进行任何转换。如果换行符是任何其他合法值,则写入的任何'\n' 字符都会被转换为给定的字符串。

    【讨论】:

      【解决方案2】:

      使用python的universal newline support:

      f = open('randomthing.py', 'rU')
      fdata = f.read()
      newlines = f.newlines
      print repr(newlines)
      

      newlines 包含文件的分隔符或分隔符元组(如果文件使用混合分隔符)。

      【讨论】:

      • 这似乎只有在您先将整个文件读入内存时才有效。那是对的吗?例如,我尝试只读取前 500 个字节,当我打印出 f.newlines 时得到 None(我知道前 100 个字节中有一个 \r\n)。这似乎是一个低效的解决方案,因为这可能意味着您在内存中有两个文件副本——一个您将要写入的副本,另一个是您读取以确定行尾的副本。 :-\
      • @BryanOakley,我无法重现您描述的结果; newlines 在读取分隔符后立即更新,并在读取不同分隔符时继续更新。你确定你是用'U' 标志打开的吗?通用换行支持不是自动的(无论如何,在我的版本中)。
      • 请注意...“允许有一个额外的模式字符'U',它不再有任何影响,被认为已弃用。它以前在文本模式下启用了通用换行符,这成为Python 3.0 中的默认行为。有关更多详细信息,请参阅换行参数的文档。"
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-06
      • 1970-01-01
      • 1970-01-01
      • 2020-10-10
      相关资源
      最近更新 更多