'\r' 在 Python `csv.writer()` 中不能作为 `lineterminator`

1 python windows csv writer

我在 Windows 上工作。我有一个 Python 文件来创建一个新的 CSV 文件,我使用记事本(甚至通过Microsoft Excel)查看该文件。

import csv
data = [['fruit','quantity'], ['apple',5], ['banana',7],['mango',8]]
with open('d:\lineter.csv', 'w') as l:
    w = csv.writer(l,delimiter='|', lineterminator='\r')
    w.writerows(data)
Run Code Online (Sandbox Code Playgroud)

记事本中的结果文件:

import csv
data = [['fruit','quantity'], ['apple',5], ['banana',7],['mango',8]]
with open('d:\lineter.csv', 'w') as l:
    w = csv.writer(l,delimiter='|', lineterminator='\r')
    w.writerows(data)
Run Code Online (Sandbox Code Playgroud)

回车是否\r有效?它的工作原理就像lineterminator=''记事本中。但在 Excel 中,它的工作方式类似于 '\n'。

输出似乎没有实现回车。当我lineterminator用作:

w = csv.writer(l, delimiter='|', lineterminator='*\r*\n')
Run Code Online (Sandbox Code Playgroud)

记事本中的输出是:

fruit|quantityapple|5banana|7mango|8
Run Code Online (Sandbox Code Playgroud)

这在这里也很明显。

'\r'lineterminator在 writer()中是如何工作的?或者那里正在发生其他事情?

Gab*_*les 8

更简短的答案:

何时使用回车 (CR, \r) 与换行符 (LF, \n) 与两者 (CRLF, \r\n) 在 Windows、Mac 和 Linux 上的文本编辑器中显示新行:

'\r' 如何在 writer() 中的 lineterminator 中工作??

它在csv.writer(). 这真的不是 Python、CSV 或编写器的问题。这是操作系统的历史差异(实际上,更准确地说,它是特定程序的差异)可以追溯到 1960 年代左右。

或者那里正在发生其他事情?

是的,就是这个。

您的记事本版本无法将回车符 ( \r)识别为用于显示新行的字符,因此不会在记事本中如此显示。其他文本编辑器,例如Sublime Text 3,即使在 Windows 上也可能会。

直到大约 2018 年左右,Windows 和记事本都需要一起回车 + 换行符 ( \r\n)来显示新行。将此与 Mac 和 Linux 形成对比,后者只需要.\n

解决方案是\r\n在 Windows 上\n用于换行,在 Mac 或 Linux 上单独用于换行。您还可以在查看或编辑文本文件时尝试使用不同的文本编辑器,例如 Sublime Text,或者升级您的 Windows 或记事本版本(如果可能的话),因为大约在 2018 年左右, Windows 记事本开始接受\r单独作为有效的旧版本 - Mac 风格的换行符。

(来自 OP 在此答案下的评论):

那为什么要给'\r\n'???

当程序员编写程序时,程序员可以让程序做程序员想让程序做的任何事情。当Windows程序员做Windows和记事本,他们决定把节目做什么,如果它有一个\r,没有什么,如果它有一个\n,并做了新的生产线,如果它得到了\r\n 起来。就这么简单。该程序完全按照程序员的要求执行,因为他们决定这就是他们希望程序运行的方式。因此,如果您想在 Windows 的旧版(2018 年之前)记事本中添加新行,则必须执行程序员要求您执行的操作才能获得它。\r\n是吗。

这可以追溯到电传打字机的时代(阅读此处的“历史”和“表现”部分),以及有关“电传打字机”/“电传打字机”/“电传打字机或 TTY 机器”的页面

打字机或机电打印机可以在纸上打印字符,并执行诸如将马车移回同一行的左边距回车)、前进到下一行的同一列换行)等操作.
来源;强调添加)

电传打字机上的机械回车按钮(\r现在在计算机上)的意思是:“将回车(打印头)返回到行首”(意思是:页面的最左侧),换行机械机构位于电传打字机(\n现在在电脑上)的意思是:“把纸卷起来一行,这样我们就可以在下一行打字了。” 如果没有机械换行 ( \n) 动作,\r仅回车 ( ) 就会将机械打印头移动到页面的最左侧,并使您在已经输入的单词的顶部重新输入!并且没有回车机械动作(\r在电脑上),换行机械动作(\n) 单独会导致您只在页面上每个新行的最右侧的最后一列中键入,永远无法再次将打印头返回到页面的左侧!在机电式电传打字机上,它们必须使用:回车会将打印头带回页面的左侧,换行操作会将打印头向下移动到下一行因此,据推测,Windows程序员认为这是合乎逻辑的,以保持这一传统活着,他们决定需要双方\r\n 起来建立一个计算机上新的生产线,因为这是它必须对机电电传打字机传统做

阅读下文了解详情。

详细信息(较长的答案):

我对正在发生的事情有一些想法,但让我们来看看。我相信我们有两个问题需要回答:

  1. 是否\r实际存储到文件中?
  2. 记事本是否真的显示了\r,如果没有,为什么不呢?

所以,对于#1。让我们在 Linux Ubuntu 20.04 (Focal Fossa)上测试一下:

这个程序:

#!/usr/bin/python3

import csv
data = [['fruit','quantity'], ['apple',5], ['banana',7],['mango',8]]
with open('d:\lineter.csv','w') as l:
    w = csv.writer(l, delimiter='|', lineterminator='\r')
    w.writerows(data)
Run Code Online (Sandbox Code Playgroud)

生成此文件:d:\lineter.csv。如果我在Sublime Text 3 文本编辑器中打开它,我会看到:

#!/usr/bin/python3

import csv
data = [['fruit','quantity'], ['apple',5], ['banana',7],['mango',8]]
with open('d:\lineter.csv','w') as l:
    w = csv.writer(l, delimiter='|', lineterminator='\r')
    w.writerows(data)
Run Code Online (Sandbox Code Playgroud)

到现在为止还挺好。让我们看看hexdump命令行中的字符:

hexdump -c显示\r人物,果然!

fruit|quantity
apple|5
banana|7
mango|8
Run Code Online (Sandbox Code Playgroud)

您也可以使用hexdump -C以十六进制显示字符,再次,我\r将文件中的 视为十六进制0d字符,这是正确的。

好的,所以我在 Linux 中的VirtualBox虚拟机中启动了 Windows 10 Professional ,并在记事本中打开了相同的文件,并且....它也可以工作!看截图:

在此处输入图片说明

但是,请注意我圈出的“Macintosh (CR)”部分。我正在运行最新版本的 Windows 10 专业版。我敢打赌您使用的是没有此修复程序的旧版记事本,您不会在这里说。 这是因为 33 年来记事本没有处理回车,或者\r作为有效的行尾,所以它不会这样显示。请参阅此处:Windows 记事本在 33 年后修复:现在它终于可以处理 Unix、Mac OS 行尾了

由于可追溯到电传打字机和摩尔斯电码的历史差异(阅读此处的“历史”和“表示”部分),不同的系统决定让它们的文本编辑器以不同的方式处理行尾。从上面文章(强调):

记事本以前只能识别 Windows 行(EOL) 字符,特别是回车符 (CR, \r, 0x0d) 和换行符 (LF, \n, 0x0a) 在一起

对于老式 Mac OS,EOL 字符只是 Carriage Return (CR, \r, 0x0d)对于 Linux/Unix,它只是 Line Feed (LF, \n, 0x0a)。自 Mac OS X 以来,现代 macOS 遵循 Unix 约定。

所以,我们这里有以下内容在文本编辑器中显示为换行符:

  1. 老式 Mac:\r仅CR ( )
  2. Windows 记事本直到 2018 年: CR 和 LF 一起使用 ( \r\n)
  3. Linux:\n仅LF ( )
  4. 现代 Mac:\n仅LF ( )
  5. 现代 Windows 记事本(约 2018 年及以后):上述任何场景。

因此,对于的Windows,只是坚持始终使用\r\n一个换行符,并为Mac或Linux操作系统,只是坚持始终使用\n一个换行符,除非你要保证老派(即预2019 :))Windows兼容性您的文件,在这种情况下,您也应该使用\r\n换行符。


请注意,对于 Sublime Text 3,我只是在Preferences 中搜索了首选项设置并找到此设置:

$ hexdump -c d\:\\lineter.csv
0000000   f   r   u   i   t   |   q   u   a   n   t   i   t   y  \r   a
0000010   p   p   l   e   |   5  \r   b   a   n   a   n   a   |   7  \r
0000020   m   a   n   g   o   |   8  \r
0000028
Run Code Online (Sandbox Code Playgroud)

因此,要在运行 Sublime Text 的任何操作系统上使用约定,默认值是“系统”。但是,要在 Sublime Text 中编辑和保存文件时强制使用 'windows' (CRLF) 行结尾,请使用以下命令:

    // Determines what character(s) are used to terminate each line in new files.
    // Valid values are 'system' (whatever the OS uses), 'windows' (CRLF) and
    // 'unix' (LF only).
    "default_line_ending": "system",
Run Code Online (Sandbox Code Playgroud)

并强制使用 Unix(Mac 和 Linux)LF-only 行结束设置,请使用以下命令:

"default_line_ending": "windows",
Run Code Online (Sandbox Code Playgroud)

在记事本编辑器中,我找不到要配置的此类设置。这是一个简单的编辑器,仅适用于 Windows 行尾的 33 年。

补充阅读:

  1. https://en.wikipedia.org/wiki/Teleprinter
  2. https://en.wikipedia.org/wiki/Newline#History
  3. 是换行 = \n 还是 \r\n?
  4. 为什么 Windows 使用 CR LF?
  5. [我还需要阅读和学习] Unix & Linux:为什么 Linux 使用 LF 作为换行符?
  6. [我仍然需要阅读和学习] Retrocomputing: 当 Unix 是旧系统时,为什么 Windows 使用 CR+LF 而 Unix 只是 LF?

  • 我认为你真正指的是电传打字机,而不是打字机。旧的机械打字机有一个杠杆可以移动到下一行,它会移动到页面的左侧,并将纸张一次性推进一行。早期的 CRT 显示器保留了电传打字机的惯例。 (2认同)