为什么在python中以'w'模式打开文件时会截断

时间:2010-12-30 11:12:30

标签: python

我正在阅读Zed Shaw的Python书。我目前正致力于开放和阅读文件章节。我想知道为什么我们需要进行截断,当我们已经在'w'模式下打开文件时?

print "Opening the file..."
target = open(filename, 'w')

print "Truncating the file. Goodbye!"
target.truncate()

8 个答案:

答案 0 :(得分:41)

这是多余的,因为您注意到,在写入模式下打开将覆盖该文件。有关Python文档的Input and Output部分的更多信息。

答案 1 :(得分:30)

因此,Zed Shaw对已经被截断的文件调用truncate()。好的,这是毫无意义的。他为什么这样做?谁知道!?问他!

也许他这样做表明该方法存在?可能是,但那将是非常愚蠢的,因为我作为程序员在15年内从未需要截断文件,所以它在新手书中没有位置。

也许他这样做是因为他认为他必须截断文件,而他根本不知道这是毫无意义的?

也许他故意混淆新手?这符合他的一般作案手法,这似乎是故意无缘无故地惹恼人们。

更新:他这样做的原因现在很清楚了。在后面的版本中,他将这个问题列为本章中的“常见问题”,并告诉您去阅读文档。因此有:

  1. 教您阅读文档。
  2. 在复制粘贴之前,了解从某处复制粘贴的代码的每个部分。
  3. 你可以辩论这是否是一种好的教学风格,我不知道。

    “我不理解Zed Shaws书的帮助”这个问题的数量已经减少了,所以我不能说它比任何其他书都差,这可能意味着它比许多人好。 : - )

答案 2 :(得分:18)

如果您在提出问题之前先阅读问题,他会为您解答:

  

额外信用:“如果您觉得不明白这一点,请返回   通过并使用评论技巧让它在你的脑海中消失。   每行上面一条简单的英文评论将帮助您理解,   或者至少让你知道你需要多研究一下。

     

编写一个类似于上一个使用readargv的练习的脚本   阅读刚刚创建的文件。

     

此文件中的重复次数过多。使用字符串,格式和   转义只打印一个line1line2line3   target.write()命令而不是6。

     

找出为什么我们必须传递'w'作为额外参数才能打开。暗示:   打开试图通过让你明确说你想写一个安全   文件。

     

如果您使用'w'模式打开文件,那么您真的需要吗?   target.truncate()

     

去阅读Python的open函数的文档,看看是否属实。“ -    Zed Shaw

他明确地希望你自己找到这些东西,这就是为什么他的额外功劳很重要。

他还明确表示他希望你注意细节。每件小事都很重要。

答案 3 :(得分:9)

虽然在'w'模式下打开时截断是没有用的,但在'r +'中它很有用。虽然这不是OP的问题,但我会把这个留在这里给那些像我一样在谷歌领先的人。

假设您打开(使用模式'r +',记住没有'rw'模式)5行缩进的json文件并将json.load - ed对象修改为仅3行。如果在将数据写回文件之前target.seek(0),最终会产生2行尾随垃圾。如果你target.truncate(),你就不会。

我知道这似乎很明显,但我在这里是因为我正在修复一个在多年后保持完全相同大小的对象之后发生的错误...由于签名算法的改变而缩小了。 (不显而易见的是我必须添加的单元测试以防止将来发生这种情况。我写了我最长的文档字符串,解释了为什么我用2种荒谬的算法来测试签名。)

希望这有助于某人。

答案 4 :(得分:6)

使用truncate(),您可以根据文件中当前所处的位置声明要删除的文件的数量。如果没有参数,truncate()就像w一样,而w总是只是擦除整个文件。所以,这两种方法可以相同,但不一定。

答案 5 :(得分:1)

这只是标准posix语义的反映。见男人fopen(3)。 Python只是包装它。

答案 6 :(得分:0)

在写入模式下打开文件时,会截断原始文件(之前删除的所有内容)。然后你写的任何内容都会被添加到文件中。问题是,write想要从头开始添加信息,并在指针留在末尾时引发IOError。对于这种类型的写作,你想使用append(使用' a +'参数打开文件)。

答案 7 :(得分:0)

场景:
我当时正在制作一个勒索软件,需要对文件进行加密,我的目的不是要加密整个文件,而仅仅是为了破坏它,这是因为我希望它能快速执行任务,从而节省了加密所有文件的时间,所以我决定只编辑一些文本。
现在 如果我使用 write ,那么我的目的就被破坏了,因为我必须将文件a写入z。那我该怎么办?
好在这里 截断 即可使用。

下面是我的代码,该代码仅在文件中使用最后16位数字的令牌:

with open('saver.txt', 'rb+') as f:
    text_len = len(f.read())
    f.truncate(text_len-16)
    f.close()

我打开文件
截断文件中的16个字符,稍后我会替换。
请注意,我在只读模式下使用它,如果我在写模式下使用,则File将被完全截断,并且当我们输入truncate命令时,它将抛出错误。
8.4年后回答这个问题。 :)