2012-07-16 3 views
2

이것이 잘못된 행동을 일으키는 지 궁금했습니다. 테스트 케이스를 실행하고 오류가 없으므로 OK라고 가정합니다. 파이썬이 내가 존재해야한다고 가정 한 문제를 어떻게 다루는 지 알고 싶었습니다. 파일 참조 변수 덮어 쓰기

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

print fileinfo 

나는 문으로는 (() 목록 .close 할 수 없다는 대한 몇 가지 오류가 발생) 종료 문제가 발생할 것 "FILEINFO"overwritting 생각했다. with 문은 파일 참조의 로컬 복사본을 유지합니까? 감사!

+0

@ Levon 저는 이것을하지 않습니다. 파이썬이 어떻게이 문제를 해결하는지 궁금해하고있었습니다. 학습을 위해서 배웁니다. –

+0

아 .. 알았어, 충분 해. 나는 그것이 범위를 좁히는 질문 유형이고 'with' – Levon

답변

5

물론 파이썬은 with 문에 사용 된 개체에 대한 내부 참조를 유지합니다. 그렇지 않으면 as 절을 사용하지 않을 때 어떻게 작동합니까? 실제로

구체적 상황에 맞는 매니저를 연구 주제로 보았다이 발견 (나는 긍정적 아니라고하지만 self.gen에 저장 정확히) 파일 객체의 로컬 참조를 저장 않는 문

+0

위대한 지적이라고 생각한다. 컨텍스트 관리자 (이전에 나를 도망 쳤었던)를 연구 할 것을 약속했습니다. –

1

하는 관심있는 사람들을 위해 약간 더 자세하게 설명합니다.

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