【问题标题】:Using yield for file handling?使用产量进行文件处理?
【发布时间】:2019-08-28 11:24:54
【问题描述】:

我想知道使用yield进行文件处理是否是一种好习惯,

所以目前我使用一个函数 f()

f 遍历文件对象列表并产生文件对象。


files = []
for myfile in glob.glob(os.path.join(path, '*.ext')):
    f = open(myfile, 'r')
    files.append(f)

def f():
    for f_obj in files:
        yield f_obj
        f_obj.close()

for f_obj in f():
    // do some processing on file.

这是在 Python 中处理文件的正确方法吗?

【问题讨论】:

  • 什么是files?它是字符串列表(文件路径)还是它们已经打开文件对象?
  • 它们是打开的文件对象,我想知道这样使用yield是否安全,因为函数f被挂起并返回到下一行。
  • 这太模糊了。我会更担心你从哪里得到files,以及你如何管理资源(以及为什么你首先有一个可迭代的打开句柄)。
  • 也就是说,files 是我通过浏览目录获取的打开文件对象的列表。我已将其添加到代码中。

标签: python python-3.x


【解决方案1】:

如果您正在阅读文本文件(例如 CSV),则产量非常适合使您的源代码成为生成器。您的代码有一点问题是 f_obj 非常通用,因此您无法使用 f() 函数完成很多工作。

yield 的简单示例正在读取 CSV 文件 - lines() 将您的文件名转换为单个行的流。类似的东西here(旨在减少内存中的数据)。

import csv 

def lines(path):
    with open(path, 'r', newline='') as f:
        for line in csv.reader(f):
            yield line

from pathlib import Path
Path("file.txt").write_text("a,1,2\nb,20,40") 

gen = lines("file.txt")
print(next(gen))
print(next(gen))

以一般的方式,您最初介绍了yield 的使用,我认为它缺乏意图并且使代码阅读者感到困惑,为什么要这样做,但这是主观的。

【讨论】:

  • 二进制文件呢?为什么它们不合适?
  • 为什么不呢?我的观点是,对于二进制文件,您将使用“rb”打开它,并以不同的方式处理项目分隔符。我没有一个可以将二进制文件中的序列包装到生成器中的直接示例,但这肯定是一种情况。
猜你喜欢
  • 2018-08-14
  • 1970-01-01
  • 1970-01-01
  • 2015-11-21
  • 1970-01-01
  • 2015-09-05
  • 2019-07-10
  • 2016-06-18
相关资源
最近更新 更多