【问题标题】:Python file.write creating extra carriage returnPython file.write 创建额外的回车
【发布时间】:2011-04-30 20:36:24
【问题描述】:

我正在使用 python 将一系列 SQL 语句写入文件。模板字符串如下所示:

store_insert = '\tinsert stores (storenum, ...) values (\'%s\', ...)'

我正在像这样写入文件:

for line in source:
    line = line.rstrip()
    fields = line.split('\t')
    script.write(store_insert % tuple(fields))
    script.write(os.linesep)

但是,在结果输出中,我在每行的末尾看到 \r\r\n,而不是我期望的 \r\n。为什么?

【问题讨论】:

  • % 字符串格式现在已经过时了;首选成语是str.format =)
  • 您是以文本模式还是二进制模式打开文件?您使用的是哪个操作系统?
  • Windows,我刚刚做了一个 open(file, 'r')
  • 哦,对于我打开的输出文件(outputFile,'w')
  • 好的,我使用“open(file, 'wb')”打开文件(对于二进制模式),这解决了问题。为什么在文本模式下打开文件时python会将我的\r\n转换为\r\r\n?

标签: python windows eol


【解决方案1】:

\n 转换为 os.linesep 用于以文本模式打开的文件。因此,当您在 Windows 上将os.linesep 写入文本模式文件时,您会写入\r\n,然后\n 会被转换为\r\r\n

另见the docs

在编写以文本模式打开的文件时,不要使用 os.linesep 作为行终止符(默认);在所有平台上使用单个 '\n'。

【讨论】:

  • +1 很好找到!这实际上并没有发生在我身上(Win7),也许这是一个依赖于 Windows 的事情?
  • 我也在使用 Windows 7,但这解释了它。 +1 并回答!
【解决方案2】:

使用 Python 3

open() 引入了新参数newline,它允许指定一个字符串,任何出现的\n 都将被转换为。

传递一个空字符串参数newline='' 会禁用翻译,保留新行字符。仅对文本模式有效。

From the documentation

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

【讨论】:

  • 有关用例和详细说明,请参阅here
  • os.open 没有换行参数。但是open 确实如此。 os.open 有一个 O_BINARY 标志,它做同样的事情。
【解决方案3】:

文本文件在不同的操作系统上具有不同的行尾,但使用具有一致行尾字符的字符串会很方便。 Python 继承了 C 的约定,即使用'\n' 作为通用行结束字符,并在必要时依赖文件读写函数进行转换。如果文件以默认的text 模式打开,则读取和写入函数知道要执行此操作。如果您在打开文件时将b 字符添加到模式字符串中,则会跳过此翻译。

【讨论】:

    【解决方案4】:

    参见open() 文档:

    除了标准的 fopen() 值模式之外,模式可能是 'U' 或 'rU'。 Python 通常是用通用换行支持构建的;提供 'U' 将文件作为文本文件打开,但行可能被以下任何一种终止:Unix 行尾约定 '\n'、Macintosh 约定 '\r' 或 Windows 约定 '\ r\n'。所有这些外部表示都被 Python 程序视为“\n”。如果 Python 是在没有通用换行支持的情况下构建的,则带有“U”的模式与普通文本模式相同。请注意,如此打开的文件对象还有一个名为 newlines 的属性,其值为 None(如果尚未看到换行符)、'\n'、'\r'、'\r\n',或包含所有看到的换行符类型。

    【讨论】:

    • @AndiDog:我认为他的意思是,当他用 open('', 'r') 打开一个文件后,他确实看到了 \r\r\n 并且他认为他确实只写了 '\r\n' (windows),所以我告诉他,当他打开他的文件时 open() 会自动将 \r\n 添加到他的数据中,所以 '\r\n' + ' \r\n' = '\r\r\n' , '\n' 被去掉了要我再详细说明吗???
    • 不,我实际上使用的是用 open(file, 'w') 打开的单独的输出文件。更改为 open(file, 'wb') 解决了问题,但我不完全确定我理解为什么
    【解决方案5】:

    为我工作:

    >>> import tempfile
    >>> tmp = tempfile.TemporaryFile(mode="w+")
    >>> store_insert = '\tinsert stores (storenum, ...) values (\'%s\', ...)'
    >>> lines = ["foo\t\t"]
    >>> for line in lines:
    ...     line = line.rstrip()
    ...     fields = line.split("\t")
    ...     tmp.write(store_insert % tuple(fields))
    ...     tmp.write(os.linesep)
    ...
    >>> tmp.seek(0)
    >>> tmp.read()
    "\tinsert stores (storenum, ...) values ('foo', ...)\r\n"
    

    你确定这是正在运行的代码,os.linesep 是你认为的那样吗?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-08-03
      • 2011-03-12
      • 1970-01-01
      • 2019-04-11
      相关资源
      最近更新 更多