2

我很好奇这是否会导致任何不良行为。我运行了一个测试用例并且没有错误,所以我认为它没问题(尽管可能不是好的做法)。只是想知道 python 如何处理我认为应该存在的问题?

with open("somefile.txt","r") as fileinfo:
    fileinfo = fileinfo.readlines()

print fileinfo

我认为覆盖“fileinfo”会导致退出 with 语句的问题(引发一些关于无法 .close() 列表的错误)。with 语句是否保留文件引用的本地副本?谢谢!

4

2 回答 2

5

当然,Python 保留了对with语句中使用的对象的内部引用。否则当您不使用该as子句时它将如何工作?

于 2012-07-16T19:46:21.623 回答
1

with 语句确实存储了对文件对象的本地引用(尽管我不确定 self.gen 中存储的内容)

研究了该主题,专门研究了上下文管理器,发现这为感兴趣的人提供了更多细节。

class GeneratorContextManager(object):
    def __init__(self, gen):
        # Store local copy of "file reference"
        self.gen = gen

        def __enter__(self):
            try:
                return self.gen.next()
            except StopIteration:
                raise RuntimeError("generator didn't yield")

        def __exit__(self, type, value, traceback):
            if type is None:
                try:
                    self.gen.next()
                except StopIteration:
                    return
                else:
                    raise RuntimeError("generator didn't stop")
            else:
                try:
                    self.gen.throw(type, value, traceback)
                    raise RuntimeError("generator didn't stop after throw()")
                except StopIteration:
                    return True
                except:
                    # only re-raise if it's *not* the exception that was
                    # passed to throw(), because __exit__() must not raise
                    # an exception unless __exit__() itself failed.  But
                    # throw() has to raise the exception to signal
                    # propagation, so this fixes the impedance mismatch 
                    # between the throw() protocol and the __exit__()
                    # protocol.
                    #
                    if sys.exc_info()[1] is not value:
                        raise

def contextmanager(func):
    def helper(*args, **kwds):
        return GeneratorContextManager(func(*args, **kwds))
           return helper
于 2012-07-16T19:57:52.490 回答