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 に何が保存されているかは正確にはわかりません)。

トピックを調べて、特にコンテキストマネージャーを調査したところ、興味のある人のためにもう少し詳細を提供する this が見つかりました。

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 に答える