【问题标题】:line-by-line file processing, for-loop vs with逐行文件处理,for-loop vs with
【发布时间】:2012-06-23 05:23:19
【问题描述】:

我试图了解这些之间的权衡/差异 逐行处理打开文件的方式

with open('data.txt') as inf:
    for line in inf:
       #etc

for line in open('data.txt'):
   # etc

我了解使用 with 可确保文件在 退出“with-block”(套件?)(或反例)。所以自从我在这里了解到with,我就一直在使用它。

回复for-loop: 从网上搜了一圈SO,好像文件有没有 退出for-loop 时关闭是否依赖于实现?和 我找不到有关此构造如何处理的任何信息 例外。有人知道吗?

如果我对以上任何内容有误,我会很感激更正, 否则有理由使用for 构造 with? (假设你有选择,即不受 Python 版本限制)

【问题讨论】:

    标签: python file-io for-loop with-statement


    【解决方案1】:

    这个问题

    for line in open('data.txt'):
       # etc
    

    是你没有明确引用打开的文件,那么你如何关闭它? 懒惰的方法是等待垃圾收集器清理它,但这可能意味着资源没有及时释放。

    所以你可以说

    inf = open('data.txt')
    for line in inf:
       # etc
    inf.close()
    

    现在,如果在 for 循环中出现异常会发生什么?该文件不会被明确关闭。

    添加try/finally

    inf = open('data.txt')
    try:
        for line in inf:
           # etc
    finally:
        inf.close()
    

    这是很多代码来做一些非常简单的事情,所以 Python 添加了with 以使这段代码能够以更易读的方式编写。这让我们到了这里

    with open('data.txt') as inf:
        for line in inf:
           #etc
    

    所以,这是打开文件的首选方式。如果你的 Python 对于 with 语句来说太旧了,你应该在生产代码中使用 try/finally 版本

    【讨论】:

      【解决方案2】:

      with 语句仅在 Python 2.5 中引入 - 只有当您对早期版本有向后兼容性要求时,您才应该使用后者。

      更清晰一点

      引入了 with 语句(如您所知)以包含 try/except/finally 系统 - 这不是很好理解,但没关系。在 Python(C 中的 Python)中,它的实现将关闭打开的文件。语言本身的规范并没有说......所以IPython,JPython等......可以选择保持文件打开,内存打开等等,而不是在下一个GC周期之前释放资源(或者根本没有,但是CPython GC 不同于 .NET 或 Java 的...)。

      我认为我听到的唯一反对意见是它增加了另一个缩进级别。

      总结一下:

      否则,您仍然可以正常处理异常,并且 finally 块会在发生异常时关闭资源。

      为我工作!

      【讨论】:

      • 好点..当您可以选择问题时,我应该提出一些内容-即,您不受版本限制..我会更新问题。那么你的投票会投给with吗?
      • 我认为缩进是一个好处,因为它指定了在给定上下文下的部分。无论如何,您都必须缩进以将整个块包装在尝试中,除非在 finally 块中关闭文件
      • @jdl 好点 - 但请让大家知道缩进问题不是我提出的问题 - 只是我提到的一个问题,因为几年前在列表和组中注意到它。
      【解决方案3】:
      import os
      
      path = "c:\\fio"
      longer_path = "c:\\fio\\"
      # Read every file in directory
      for filename in os.listdir(path):
          print()
          print("Here is the file name",filename)
          inf = open(longer_path+filename)
          try:
              for line in inf:
                  print(line,end='')
          finally:
              inf.close()
      
      #output
      Here is the file name a.txt
      mouse
      apple
      Here is the file name New Text Document - Copy.txt
      cat
      Here is the file name New Text Document.txt
      dog
      

      【讨论】:

      • 欢迎来到 Stack Overflow!在 Stack Overflow 上添加一个解释为什么你的解决方案应该工作是一个很好的做法。更多信息请阅读How To Answer
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-07-28
      • 2017-06-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多