Python Custom Iterator:关闭StopIteration上的文件

jsj*_*jsj 8 python file-io iterator

我编写了一个迭代器类,在其中打开一个文件__init__.

def __init__(self, path):
    self.file = open(path, "r")
Run Code Online (Sandbox Code Playgroud)

迭代完成后如何自动关闭该文件?

完整课程:

class Parse(object):
    """A generator that iterates through a CC-CEDICT formatted file, returning
   a tuple of parsed results (Traditional, Simplified, Pinyin, English)"""
    def __init__(self, path):
        self.file = open(path, "r")

    def __iter__(self):
        return self

    def __is_comment(self, line):
        return line.startswith("#")

    def next(self):
        #This block ignores comments.
        line = self.file.readline()
        while line and self.__is_comment(line):
            line = self.file.readline()

        if line:
            working = line.rstrip().split(" ")
            trad, simp = working[0], working[1]
            working = " ".join(working[2:]).split("]")
            pinyin = working[0][1:]
            english = working[1][1:]
            return trad, simp, pinyin, english

        else:
            raise StopIteration()  
Run Code Online (Sandbox Code Playgroud)

Ned*_*der 11

编写整个事物的更好方法是将开头和迭代保持在一个位置:

class Parse(object):
    """A generator that iterates through a CC-CEDICT formatted file, returning
    a tuple of parsed results (Traditional, Simplified, Pinyin, English)"""
    def __init__(self, path):
        self.path = path

    def __is_comment(self, line):
        return line.startswith("#")

    def __iter__(self):
        with open(self.path) as f:
            for line in f:
                if self.__is_comment(line):
                    continue

                working = line.rstrip().split(" ")
                trad, simp = working[0], working[1]
                working = " ".join(working[2:]).split("]")
                pinyin = working[0][1:]
                english = working[1][1:]
                yield trad, simp, pinyin, english
Run Code Online (Sandbox Code Playgroud)

这将等待打开文件,直到您真正需要它,并在完成后自动关闭它.它的代码也少了.

如果你真的想进入"发电机真棒!" 心态:

def skip_comments(f):
    for line in f:
        if not.startswith('#'):
            yield line

...

    def __iter__(self):
        with open(self.path) as f:
            for line in skip_comments(f):
                working = ....
Run Code Online (Sandbox Code Playgroud)