-
Python3 with catchProgramming Language/Python3 2021. 10. 25. 19:01

withstatementpython에서
with문을 사용하는 것은 파일을 읽을 때, 장점이 있다.with open("./note.txt") as f: text = f.read() # f.close()with문이 종료할 때 별도로.close()를 하지 않아도 종료해주기 때문에 안전하게 파일에 접근할 수 있다.
그렇다면 내 생각엔with문으로 파일을 읽는 동안 발생하는 에러에 대해서with except문같은 구문이 있지 않을까 생각했다.
결론
결론부터 말하면, 그러한 문법은 존재하지 않았다.
아래의 답변은with문을try로 감싸거나, 파일을 열 때try로 감싸고 그 후 에러가 없는 경우with를 쓰는 코드를 보여주고 있다.- try-with
from __future__ import with_statement try: with open( "a.txt" ) as f : print f.readlines() except EnvironmentError: # parent of IOError, OSError *and* WindowsError where available print 'oops'- try open-else with
try: f = open('foo.txt') except IOError: print('error') else: with f: print f.readlines()내 결론
난 위의 방법이 아닌 그저
with문을 안쓰는 쪽을 선택했다.
Deep dive
그런데 아직도 이상하다. 왜 지원해주지 않는걸까?
stackoverflow catching-an-exception-while-using-a-python-with-statement에서 a_guest의 답변에 따르면ContextManager때문이라고 한다.자세한 내용까지는 다 이해하지 못했지만, 개략적으로 이야기하자면
ContextManager의 동작방식때문이라고 한다. PEP 343의 예시에 따르면 아래의 코드와with문이 동일한 형태라고 한다.import sys try: mgr = ContextManager() except ValueError as err: print('__init__ raised:', err) else: try: value = type(mgr).__enter__(mgr) except ValueError as err: print('__enter__ raised:', err) else: exit = type(mgr).__exit__ exc = True try: try: BLOCK except TypeError: pass except: exc = False try: exit_val = exit(mgr, *sys.exc_info()) except ValueError as err: print('__exit__ raised:', err) else: if not exit_val: raise except ValueError as err: print('BLOCK raised:', err) finally: if exc: try: exit(mgr, None, None, None) except ValueError as err: print('__exit__ raised:', err)코드에서는 아래와 같은 경우에서
raise가 발생한다. (코드에서는 print로 표시되어 있다.)ContextManager.__init__ContextManager.__enter__- the body of the
with ContextManager.__exit__
with-except를 쓸 수 없는 이유는raise가 여러 곳에서 발생하기 때문이라고 이해했다.
물론except로 발생하는 모든 예외를 잡을 수 있을 것이다. 하지만 그것은 잘못된 표현법이다.
왜냐하면 외부에서 봤을 때with문은 한줄이기 때문에 하나의 뎁스?의 코드가 동작하고 반환되는 것 같지만 실제로는 여러 뎁스의 동작이 존재하기 때문에 명시적으로with-except문을 사용하게 되면, 사용자는with에서 발생한 에러에 대해 추상적으로 판단하게 될 것이다.어쨌든
with문은 굉장히 추상화되어 있는 구문이다.
좋은 표현법이라고 하기 어렵겠다.
References
'Programming Language > Python3' 카테고리의 다른 글
"private" in python (0) 2021.10.25 `pipenv`는 정말 좋다. (0) 2021.10.25 파이썬 내부 클래스에 대해 (0) 2021.10.25 Pytest에 대해 알아보자. (0) 2021.10.25 [번역] Pytest fixture (0) 2021.10.25