Python 'with' 문을 사용하는 동안 예외 포착
python 'with' 문의 예외를 처리하는 방법을 알 수 없습니다.코드가 있는 경우:
with open("a.txt") as f:
print f.readlines()
어떤 작업을 하기 위해 'file not found exception'을 처리하고 싶습니다.하지만 쓸 수 없다.
with open("a.txt") as f:
print f.readlines()
except:
print 'oops'
글씨를 쓸 수 없다
with open("a.txt") as f:
print f.readlines()
else:
print 'oops'
에워싸다with
try/except 스테이트먼트도 기능하지 않고 예외가 발생하지 않습니다.내부에서 장애를 처리하려면 어떻게 해야 합니까?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:
f = open('foo.txt')
except IOError:
print('error')
else:
with f:
print f.readlines()
이를 위한 최고의 "피토닉" 방법은with
PEP 343의 예 #6에 기재되어 있습니다.이 예에서는, 스테이트먼트의 배경을 설명합니다.
@contextmanager
def opened_w_error(filename, mode="r"):
try:
f = open(filename, mode)
except IOError, err:
yield None, err
else:
try:
yield f, None
finally:
f.close()
다음과 같이 사용됩니다.
with opened_w_error("/etc/passwd", "a") as (f, err):
if err:
print "IOError:", err
else:
f.write("guido::0:0::/:/bin/sh\n")
Python 'with' 문을 사용하는 동안 예외 포착
with 스테이트먼트를 사용할 수 있습니다.__future__
Python 2.6 이후 Import.빠르면 Python 2.5에서 구할 수 있습니다(그러나 이 시점에서는 업그레이드해야 합니다).
from __future__ import with_statement
여기 당신이 가지고 있는 가장 수정해야 할 것이 있습니다.거의 다 왔는데with
없다except
절:
with open("a.txt") as f: print(f.readlines()) except: # <- with doesn't have an except clause. print('oops')
콘텍스트 매니저의__exit__
메서드(반환되는 경우)False
이 완료되면 에러가 다시 발생합니다.만약 그것이 돌아온다면True
, 그것은 그것을 억제합니다.그open
빌트__exit__
돌아오지 않다True
단, 블록은 제외하고 한 번에 네스트하면 됩니다.
try:
with open("a.txt") as f:
print(f.readlines())
except Exception as error:
print('oops')
표준 보일러 플레이트: 베어 사용 안 함except:
잡히는 것BaseException
기타 가능한 모든 예외와 경고를 포함합니다.적어도 다음과 같이 구체화해야 합니다.Exception
이 에러에 대해서는, 캐치할 수 있습니다.IOError
대처할 준비가 되어 있는 오류만 캐치합니다.
이 경우 다음을 수행합니다.
>>> try:
... with open("a.txt") as f:
... print(f.readlines())
... except IOError as error:
... print('oops')
...
oops
화합물에서 발생할 수 있는 예외 발생원 간의 구별with
진술
에서 발생하는 예외 간의 구별with
문장은 서로 다른 장소에서 생성될 수 있기 때문에 까다롭습니다.예외는 다음 장소 중 하나(또는 해당 장소에서 호출된 기능)에서 제기할 수 있습니다.
ContextManager.__init__
ContextManager.__enter__
- 의 몸통
with
ContextManager.__exit__
자세한 내용은 Context Manager Type에 대한 매뉴얼을 참조하십시오.
이러한 다른 케이스를 구별하려면 , 이 케이스를 정리하는 것만으로,with
에try .. except
충분하지 않습니다.다음 예를 생각해 보겠습니다(사용).ValueError
예를 들어, 물론 다른 예외 유형으로 대체할 수 있습니다.)
try:
with ContextManager():
BLOCK
except ValueError as err:
print(err)
★★★★★★★★★★★★★★★★★★.except
를 모두 포착하기 할 수 .를 " " " 로 with
, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , , .__init__
★★★★★★★★★★★★★★★★★」BLOCK / __enter__ / __exit__
:
try:
mgr = ContextManager()
except ValueError as err:
print('__init__ raised:', err)
else:
try:
with mgr:
try:
BLOCK
except TypeError: # catching another type (which we want to handle here)
pass
except ValueError as err:
# At this point we still cannot distinguish between exceptions raised from
# __enter__, BLOCK, __exit__ (also BLOCK since we didn't catch ValueError in the body)
pass
은 단지 그 일에 이 되었을 뿐이다.__init__
하여 sentinel 이 sentinel 본문인지 할 수 .with
「」( 「」, 「」)의 )__enter__
( ) :
try:
mgr = ContextManager() # __init__ could raise
except ValueError as err:
print('__init__ raised:', err)
else:
try:
entered_body = False
with mgr:
entered_body = True # __enter__ did not raise at this point
try:
BLOCK
except TypeError: # catching another type (which we want to handle here)
pass
except ValueError as err:
if not entered_body:
print('__enter__ raised:', err)
else:
# At this point we know the exception came either from BLOCK or from __exit__
pass
은 '를 구별하다'에서 비롯되는 하는 것입니다.BLOCK
★★★★★★★★★★★★★★★★★」__exit__
는 '''의 본문을 때문입니다.with
__exit__
처리 방법을 결정할 수 있습니다(문서 참조).단,__exit__
원래 예외가 새 예외로 대체됩니다. 수 .except
의 with
눈치채지 못하고 이 있는 합니다.except
-가 "-"-"-"-"-"-"-"-"-"-"-"-"-"-"을 의미합니다.BLOCK
않으면 __exit__
에 따라)__exit__
는 가장 합니다.except
의
try:
mgr = ContextManager() # __init__ could raise
except ValueError as err:
print('__init__ raised:', err)
else:
entered_body = exc_escaped_from_body = False
try:
with mgr:
entered_body = True # __enter__ did not raise at this point
try:
BLOCK
except TypeError: # catching another type (which we want to handle here)
pass
except Exception as err: # this exception would normally escape without notice
# we store this exception to check in the outer `except` clause
# whether it is the same (otherwise it comes from __exit__)
exc_escaped_from_body = err
raise # re-raise since we didn't intend to handle it, just needed to store it
except ValueError as err:
if not entered_body:
print('__enter__ raised:', err)
elif err is exc_escaped_from_body:
print('BLOCK raised:', err)
else:
print('__exit__ raised:', err)
PEP 343에 언급된 동등한 형식을 사용하는 대체 접근법
PEP 343 - "with" 스테이트먼트는 동등한 "with" 버전의 Version을 지정합니다.with
여기에서는 을 쉽게 정리할 수 .try ... except
따라서 다양한 잠재적 오류 원인을 구별할 수 있습니다.
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)
통상, 심플한 어프로치로 충분합니다.
합니다.with
in a a a a try ... except
블록이면 충분합니다.특히 다양한 오류 발생원이 다른 (커스텀) 예외 유형에 의해 나타나는 경우(컨텍스트 매니저는 그에 따라 설계되어야 함) 쉽게 구별할 수 있습니다.예를 들어 다음과 같습니다.
try:
with ContextManager():
BLOCK
except InitError: # raised from __init__
...
except AcquireResourceError: # raised from __enter__
...
except ValueError: # raised from BLOCK
...
except ReleaseResourceError: # raised from __exit__
...
내가 만든 프로그램에서 이걸 사용했어:
try:
with open(os.path.join(basedir, "rules.txt")) as f:
self.rules.setText(f.read())
except FileNotFoundError:
self.rules.setText("Sorry, unable to read rules")
언급URL : https://stackoverflow.com/questions/713794/catching-an-exception-while-using-a-python-with-statement
'source' 카테고리의 다른 글
사전에 특정 키가 포함되어 있는지 테스트하는 방법 (0) | 2022.09.18 |
---|---|
Python의 문자열 비교:는 vs입니다.== (0) | 2022.09.17 |
/usr/libexec/java_home에서 반환된 Mac OS의 기본 Java VM을 변경하는 방법 (0) | 2022.09.17 |
서버가 비활성 시간대를 반환했습니다.Advanced 탭으로 이동하여 servertimezone 속성을 수동으로 설정합니다. (0) | 2022.09.17 |
SQL 구문에 오류가 있습니다. 사용 중인 MariaDB 서버 버전에 해당하는 설명서에서 nea를 사용하는 올바른 구문을 확인하십시오. (0) | 2022.09.17 |