2014-07-12 1 views
1

ID는 itertools.izip()을 사용하여 여러 파일의 행을 반복합니다. with과 함께 사용할 때 모든 파일이 닫힐 수 있도록 컨텍스트 관리자 유형을 만들었습니다.여러 파일을 반복하는 Context Manager 유형 -

class Files_Iterator(object): 
    """Sequential line iteration from multiple files 
    """ 
    def __init__(self, files): 
     """files --> list or tuple of str, file paths 
     """ 
     self.files = files 
    def __enter__(self): 
     print 'opening files' 
     self.files = map(open, self.files) 
     return it.izip(*self.files) 
    def __exit__(self, *exception_args): 
     print 'closing files' 
     for arg in exception_args: 
      print arg, 
     for thing in self.files: 
      thing.close() 
     return False 

두 질문 :

  1. 내가 올바르게 구현 한 이 작동하는 것 같다?
  2. 파일을 닫히지 않았는지 테스트하거나 신뢰할 수 있습니까?

나는 __exit__이 호출 될 때 신호를 내기 위해 print 문을 사용했습니다. 충분한 테스트입니까?

>>> with Files_Iterator(['file1.txt', 'file2.txt']) as files: 
    for lines in files: 
     print lines 
     raise Exception 


opening files 
('File1Line1\n', 'File2Line1\n') 
closing files 
<type 'exceptions.Exception'> <traceback object at 0x0313DFD0> 

Traceback (most recent call last): 
    File "<pyshell#48>", line 4, in <module> 
    raise Exception 
Exception 
>>> 
+0

아마 모든 파일을 동시에 열어 놓을 것입니다. 파일이 순차적으로 만 사용된다고 확신하는 경우, 커스텀 반복자를 반환하면 한 번에 하나의 파일 만 열리 며 바깥쪽에있는 'with'는 마지막 (단일) 파일의 정리를 처리 할 수 ​​있습니다. – Veedrac

+0

FWIW,'contextlib.contextmanager' 편의 클래스로 작성하면 더 좋을 수 있습니다. – Veedrac

+0

@Veedrac, 의도는 각 파일에서 라인을 생성하는 것입니다. - 나는 모든 파일이 동시에 열려 있어야하는지에 대해 실제로 생각하지 않았습니다. 나는'''contextlib.contextmanager''를 보았습니다. 왜 내가 그 길을 가지 않았는지 모르겠습니다. – wwii

답변

1

그것은 그래 당신은 그것을 믿을 수 있지만 명시 적으로 __exit__에 인수 이름을 것입니다, 잘 보이는 :

def __exit__(self, exc_type, exc_value, traceback): 
    print 'closing files' 
    for arg in (exc_type, exc_value, traceback): 
     print arg, 
    for f in self.files: 
     f.close() 
    return False # does not suppress the exception. 

을 그리고 예외가있는 경우 함수가 종료가,이 처리 될 때 정상적으로.

관련 문제