为什么每次我们要附加文件时都需要打开文件

时间:2018-09-10 03:29:39

标签: python

作为线程How do you append to a file?,大多数答案是关于打开文件并将其附加到文件,例如:

            $.ajax({
                url: '../url',
                dataType: "json",
                data: { data},
                method: 'post',
                success: function (data) {
                    var html, ul_menu = ''
                    ul_menu = $('#ul-menu');
                    $(data).each(function (index, menu) {
                        html = ''
                            + '<li class="has_sub">'
                                + '<a href="javascript:void(0);" class="waves-effect"><i class="mdi mdi-album"></i> <span> Menu </span> <span class="float-right"><i class="mdi mdi-plus"></i></span></a>'
                                + '<ul class="list-unstyled">'
                                    + '<li><a href="index.html?sys=hris&mod=human-resource&sub=man-power-request">Sub Menu 1</a></li>'
                                    + '<li><a href="ui-components.html">Sub Menu 2</a></li>'
                                + '</ul>'
                            + '</li>';
                        ul_menu.append(html);
                    });
                }
            });

为什么我们不只是提取def FileSave(content): with open(filename, "a") as myfile: myfile.write(content) FileSave("test1 \n") FileSave("test2 \n") 并仅在调用myfile时写入它。

FileSave

后面的代码是否更好,因为它只打开文件一次并多次写入文件? 或者,没有区别的原因是python里面的内容可以保证仅一次调用global myfile myfile = open(filename) def FileSave(content): myfile.write(content) FileSave("test1 \n") FileSave("test2 \n") 方法即可打开文件。

4 个答案:

答案 0 :(得分:5)

修改后的代码存在许多与您的问题无关的问题:您以只读模式打开文件,从不关闭文件,并且有一个global语句没什么...

让我们忽略所有这些,而只谈一遍又一遍打开和关闭文件的优点和缺点:

  • 浪费一点时间。如果您真的不走运,该文件甚至可能几乎无法从磁盘缓存中掉出来,甚至浪费更多时间。
  • 确保即使某些其他程序也正在追加到同一文件,您始终要追加到文件的末尾。 (例如,对于syslog类型的日志,这非常重要。) 1
  • 确保已将写入的数据刷新到磁盘上,这减少了程序崩溃或被杀死时丢失数据的机会。
  • 确保您在将写入内容写入磁盘后立即将其刷新。如果您尝试在同一程序或其他程序中的其他位置打开并读取文件,或者最终用户只是在记事本中打开文件,则不会丢失最后一行价值1.73KB的行,因为它们仍然 2

因此,这是一个折衷。通常,您需要这些保证之一,而性能成本并不重要。有时,这很重要,而且保证并不重要。有时候,您确实需要两者,因此您必须编写一些复杂的内容,手动缓冲位并立即写入并刷新它们。


1。正如open的Python文档所阐明的那样,这在某些 Unix系统上仍然会发生。但是,在其他Unix系统上和Windows上都没有。.

2。另外,如果您有多个作者,那么他们一次都会添加一行,而不是在每次刷新时都添加一行,这对于日志文件而言同样非常重要。

答案 1 :(得分:2)

通常global应该是avoided if possible

人们在处理文件时使用with命令的原因是它明确控制范围。完成with运算符后,将关闭文件,并丢弃文件变量。

您可以避免使用with运算符,但是必须记住要调用myfile.close()。特别是当您要处理大量文件时。

避免使用with块也避免使用全局的一种方法是

 def filesave(f_obj, string):
     f_obj.write(string)

 f = open(filename, 'a')
 filesave(f, "test1\n")
 filesave(f, "test2\n")
 f.close()

但是,此时最好还是摆脱该功能,而只是做一下:

f = open(filename, 'a')
f.write("test1\n")
f.write("test2\n")
f.close()

此时,您可以轻松地将其放在with块中:

with open(filename, 'a') as f:
    f.write("test1\n")
    f.write("test2\n")

是的。没有困难理由不做自己在做的事情。只是不是Pythonic。

答案 2 :(得分:1)

后面的代码可能更有效,但是前面的代码更安全,因为它可以确保每次调用FileSave写入文件的内容都刷新到文件系统,以便其他进程可以读取更新的文件。内容,并通过使用open作为上下文管理器在每次调用时关闭文件句柄,使其他进程也有机会写入文件(特别是在Windows中)。

答案 3 :(得分:1)

这确实取决于情况,但是这里有一些想法:

with块绝对保证一旦退出该块,文件就会关闭。 Python对于附加文件没有做出奇怪的优化。

通常,全局变量会使您的代码模块化程度降低,因此更难以阅读和维护。您可能会认为原始的FileSave函数正在尝试避免使用全局变量,但是它使用的是全局名称filename,因此您最好在此时完全使用全局文件,因为这样做可以节省一些时间I / O开销。

一个更好的选择是完全避免使用全局变量,或者至少正确使用它们。您确实不需要包装file.write的单独函数,但是如果它表示更复杂的内容,则有以下设计建议:

def save(file, content):
    print(content, file=file)

def my_thing(filename):
    with open(filename, 'a') as f:
        # do some stuff
        save(f, 'test1')
        # do more stuff
        save(f, 'test2')

if __name__ == '__main__':
    my_thing('myfile.txt')

请注意,当您将模块作为脚本调用时,在全局范围内定义的文件名将被传递到主例程中。但是,由于主例程未引用全局变量,因此您可以A)易于阅读,因为它是自包含的,并且B)对其进行测试而不必怀疑如何在不破坏其他所有内容的情况下提供输入。

此外,通过使用print而不是file.write,您可以避免手动花换行符。