source

Python 'with' 문을 사용하는 동안 예외 포착

gigabyte 2022. 9. 17. 09:56
반응형

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'

에워싸다withtry/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()

이를 위한 최고의 "피토닉" 방법은withPEP 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에 대한 매뉴얼을 참조하십시오.

이러한 다른 케이스를 구별하려면 , 이 케이스를 정리하는 것만으로,withtry .. 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__원래 예외가 새 예외로 대체됩니다. 수 .exceptwith 눈치채지 못하고 이 있는 합니다.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)

통상, 심플한 어프로치로 충분합니다.

합니다.within 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

반응형