关于Python文件行反转中rstrip('\n')作用的技术疑问
rstrip('\n')的疑问解答 我最近在读《Data Structure And Algorithm In Python》,在用栈实现文件内容行反转的功能时,对书中要求必须使用.rstrip('\n')这点产生了几个疑问,下面结合文本文件的存储逻辑来逐一拆解:
疑问1:为何会出现原第一行紧跟原第二行且无换行的情况?
咱们先搞清楚Python读取文本行的逻辑:当你用readline()或者直接遍历文件对象时,读取到的每行内容除了最后一行(如果原文件末尾没有换行符),都是自带换行符\n的。
举个例子,假设原文件内容是这样的(第二行末尾没有换行):
第一行内容 第二行内容
读取后得到的两行分别是:"第一行内容\n" 和 "第二行内容"。用栈反转的话,弹出顺序是先弹"第二行内容",再弹"第一行内容\n"。如果直接把这两个字符串写入新文件,结果就是"第二行内容第一行内容\n"——原第一行直接跟在原第二行后面,完全没有换行分隔,这就是问题的根源。
而用.rstrip('\n')处理后,我们会先把每行末尾的\n去掉,写入时再统一给每行加上\n,这样就能保证所有行之间都有正确的换行分隔。
疑问2:为何只有最后一行存在该问题?
这是文本文件的存储特性决定的:除了最后一行,其他所有行在存储时都会以\n结尾(这是文本行的标准分隔方式,用来区分不同的行)。只有最后一行,可能因为用户编辑完没有手动添加结尾换行,导致它没有\n。
当反转时,这行没有\n的内容会被放到输出文件的最开头。后面紧接着写入的是原来的倒数第二行(它本身带着\n,但这个\n是它自己的行尾分隔符,用来和原最后一行区分),直接拼接的话就会出现两行连在一起的情况。而其他行因为都自带\n,反转后它们的\n会自然起到分隔作用,不会有问题。
疑问3:既然.rstrip('\n')会删除换行符,原文件末尾是否有换行符为何会影响结果?
核心在于reverse_file的正确逻辑:我们需要消除原文件格式的差异,保证输出的每行都有统一的换行分隔。
- 如果原文件末尾有换行符,最后一行读取后是
"最后一行内容\n",经过.rstrip('\n')变成"最后一行内容",写入时再加\n,最终还是"最后一行内容\n",和原格式一致。 - 如果原文件末尾没有换行符,最后一行读取后是
"最后一行内容",.rstrip('\n')处理后还是原内容,写入时加\n,就会补上缺失的换行符。
反过来,如果不用.rstrip('\n'),当原文件末尾没有换行符时,无\n的最后一行被写入后,后面的行直接跟在它后面,没有任何分隔;而如果原文件末尾有换行符,所有行都带\n,写入时就不会有问题。所以原文件末尾的换行符状态会直接影响反转后的输出格式,而.rstrip('\n')的作用就是统一处理所有行,消除这种差异。
内容的提问来源于stack exchange,提问作者Andy Junghyun Kim

