产量&正确关闭文件对象

时间:2013-03-26 19:31:43

标签: python python-2.7

我有以下课程:

class JsonIterator(object):
    def __init__(self,folder):
        self.root = os.path.join(os.getcwd(), folder)
        self.fis = [fi for fi in os.listdir(folder) if "lyrics" in fi]

    def __iter__(self):
        i = 0
        with open(os.path.join(self.root,self.fis[i])) as f:
            yield json.load(f)
        i += 1

我的工作方式并不奏效 - 似乎没有超越第一个文件。我试过了

def __iter__(self):
    i = 0
    f = open(os.path.join(self.root, self.fis[i]))
    js = json.load(f)
    f.close()
    yield js
    i += 1

但不管怎样,len(list(JsonIterator("path/to/myfolder")))给了我1,而且我知道文件夹中有多个文件。当然,替代方案就像是

def __iter__(self):
    i = 0
    yield json.load(open(os.path.join(self.root, self.fis[i])))
    i += 1

但所有那些悬空打开的文件都会吸引我的进程被杀死的内存。

那我该怎么办?我想过写一些装饰,但我真的不明白它们是如何工作的,或者即使它解决了我的问题。

谢谢!

2 个答案:

答案 0 :(得分:3)

您需要遍历self.fis中的文件名:

class JsonIterator(object):
    def __init__(self,folder):
        self.root = os.path.join(os.getcwd(), folder)
        self.fis = [fi for fi in os.listdir(folder) if "lyrics" in fi]

    def __iter__(self):
        for fi in self.fis:
            with open(os.path.join(self.root, fi)) as f:
                obj = json.load(f)
            yield obj

答案 1 :(得分:0)

如其他答案中所述,您需要遍历__iter__()内的文件列表。这是一个使用生成器表达式执行相同操作的等效替代方法:

def __iter__(self):
    return (json.load(open(os.path.join(self.root, fi))) for fi in self.fis)

The files will be closed automatically when they are garbage collected,假设您使用的是CPython。