Python生成器如何在调用生成器的for循环突然返回时关闭文件句柄?

pla*_*pus 7 python

如果函数lookForSpecificLine返回True(也就是说,如果文件"foo.txt"包含targetLine),Python如何知道关闭文件句柄?文件"foo.txt"会保持打开状态吗?

def lines(filename):
    with open(filename, encoding='utf-8') as file:
        for line in file:
            yield line

def lookForSpecificLine(targetLine):
    for line in lines('foo.txt'):
        if targetLine == line:
            return True
    return False
Run Code Online (Sandbox Code Playgroud)

Blc*_*ght 12

只要生成器对象处于活动状态,您的文件就会保持打开状态.当生成器被垃圾收集时(lookForSpecificLine通常在函数结束时),Python将调用close它,作为PEP 342中描述的协同例程协议的一部分 .该close方法使Python GeneratorExit在它被暂停的位置(在yield语句之后)将异常抛出到生成器的代码中.由于您没有捕获该异常(通常不应该这样),它将突破循环并导致with语句关闭该文件.

请注意,如果lookForSpecificLine它更复杂并且存在导致异常的风险(可以在更高级别捕获),则可能无法快速清理事物.那是因为异常回溯会使函数的堆栈帧保持活动状态,因此不会立即对生成器进行垃圾回收,也不会关闭文件.