美文网首页Learning Python
Chapter 34: Exception Coding Det

Chapter 34: Exception Coding Det

作者: 枇杷膏_a56b | 来源:发表于2021-06-21 22:01 被阅读0次

    The try/except/else Statement

    # try/except/else
    try:
        print('doing sth')
    except name1:
        print('doing sth')
    except (name1, name2):
        print('doing sth')
    except name4 as var:
        print('doing sth')
    except:
        print('doing sth')
    else:
        print('doing sth if no exception is raised.')
    

    How try Statements Work

    • First run try blocks, the statements under try block.
    • If an exception raises and is caught, run the corresponding exception block, after that, control then resumes below the entire try statement.
    • If an exception is raised and not be caught, Python kills the program and prints a default error message.
    • If an exception does not occur, run statements under the else line (if present).
    • The empty exception clause matches all or other errors.

    In sum, except clauses catch any matching exceptions that happen while the try block is running, and the else clause runs only if no exceptions happen while the try block runs.

    Try Statement Clauses

    Table 34-1. try statement clause forms

    Clause form Interpretation
    except: Catch all (or all other) exception types.
    except name: Catch a specific exception only.
    except name as value: Catch the exception and assign its instance.
    except (name1, name2): Catch any of the listed exceptions.
    except (name1, name2) as value: Catch the listed exception and assign its instance.
    else: Run if no exceptions are raised in the try block.
    finally: Always perform this block on exit.
    • empty except clause catch all exceptions including the ones triggered by system, such as exit calls and Ctrl-C key combinations. So it is recommended to use the following statements to avoid catching system errors:
    # Exception class will catch exceptions except catching exit events.
    try:
        action()
    except Exception:
        ...
    

    The try else Clause

    # provides syntax in a try that makes what has happened obvious and unambiguous.
    try:
        ...run code...
    except IndexError:
        ...handle exception...
    else:
        ...no exception occurred...
    

    Example: default behavior:

    def gobad(x, y):
        return x / y
    
    def go_south(x):
        print(gobad(x, 0))
    
    go_south(1) 
    >>>
    ---------------------------------------------------------------------------
    ZeroDivisionError                         Traceback (most recent call last)
    <ipython-input-1-fef879750521> in <module>
          5     print(gobad(x, 0))
          6 
    ----> 7 go_south(1)
    
    <ipython-input-1-fef879750521> in go_south(x)
          3 
          4 def go_south(x):
    ----> 5     print(gobad(x, 0))
          6 
          7 go_south(1)
    
    <ipython-input-1-fef879750521> in gobad(x, y)
          1 def gobad(x, y):
    ----> 2     return x / y
          3 
          4 def go_south(x):
          5     print(gobad(x, 0))
    
    ZeroDivisionError: division by zero
    

    Often, this standard error message is all you need to resolve problems in your code.

    Catching Built-in Exceptions

    If you don't want your program terminated when Python raises an exception, simply catch it by wrapping the program logic in a try.

    def kaboom(x, y):
        print(x + y)
        
    try:
        kaboom([0, 1, 2], 'spam')
    except TypeError:
        print('Hello World.')
    print('Resuming here.') 
    
    >>>
    Hello World.
    Resuming here.
    

    The try/finally Statement

    The try/finally form is useful when you want to be completely sure that an action will happen after some code runs, regardless of the exception behavior of the program. (Such as close an opened file.)

    • The finally clause could not be mixed with except and else.
    • The formula of using combined try/except/else/finally:
      try \rightarrow except \rightarrow else \rightarrow finally

    The raise Statement

    • raise is used to trigger exceptions explicitly.

    raise instance # Raise instance of class (The most common)
    raise class # Make and raise instance of class: make an instance
    raise # Reraise the most recent exception

    The following two forms are equivalent----both raise an instance of the exception class named.

    raise IndexError
    raise IndexError()
    
    • create the instance ahead of time
    exc = IndexError()
    raise exc
    
    excs = [IndexError, TypeError]
    raise excs[0]
    

    Pass to the exception class constructor arguments that become available in the handler through the assigned instance.

    class MyExc(Exception): pass
    ...
    raise MyExc('spam')     # Exception class with constructor args
    ...
    try:
        ...
    except MyExc as X:     # Instance attributes available in handler.
        print(X.args)
    

    Scopes and try except Variables

    In Python 3.x, the exception reference name is not available after the block exits.

    try:
        1 / 0
    except Exception as X:
        print(X)
    
    >>>
    division by zero
    
    
    print(X) 
    >>>
    ---------------------------------------------------------------------------
    NameError                                 Traceback (most recent call last)
    <ipython-input-4-5f1555447371> in <module>
    ----> 1 print(X)
    
    NameError: name 'X' is not defined
    
    • The variable used in except block is removed globally even if it is defined ahead of the exception block.
    X = 99
    try:
        1 / 0
    except Exception as X:
        print(X)
    
    >>>
    division by zero
    
    
    print(X) 
    
    >>>
    print(X) 
    1
    print(X) 
    ---------------------------------------------------------------------------
    NameError                                 Traceback (most recent call last)
    <ipython-input-6-5f1555447371> in <module>
    ----> 1 print(X)
    
    NameError: name 'X' is not defined
    
    • This is unlike what happens in compression loop variables.
    X = 99
    
    >>>
    {'a', 'm', 'p', 's'}
    
    print(X) 
    >>>
    99
    

    Because of this, your should generally use unique variable names in your try statement's except clause.

    • You can save the exception if needed.
    try:
        1 / 0
    except Exception as X:
        print(X)
        save_it = X
    
    >>>
    division by zero
    
    X
    >>>
    NameError: name 'X' is not defined
    
    
    save_it
    ZeroDivisionError('division by zero')
    

    Python 3.X Exception Chaining: raise from

    raise newexception from otherexception

    The assert Statement

    The assert is mostly just syntactic shorthand for a common raise usage pattern.

    assert test, data # The data part is optional

    works like the following code:

    if __debug__:
        if not test:
           raise AssertionError(data)
    

    If the test evaluates to false, Python raises an exception: the data item (if it's provided) is used as the exception's constructor argument. Like all exceptions, the AssertionError exception will kill your program if it's not caught with a try.

    Example

    def f(x):
        assert x < 0, 'x must be negative'
        return x ** 2
    
    f(1) 
    >>>
    ---------------------------------------------------------------------------
    AssertionError                            Traceback (most recent call last)
    <ipython-input-12-3a4297a3995e> in <module>
          3     return x ** 2
          4 
    ----> 5 f(1)
    
    <ipython-input-12-3a4297a3995e> in f(x)
          1 def f(x):
    ----> 2     assert x < 0, 'x must be negative'
          3     return x ** 2
          4 
          5 f(1)
    
    AssertionError: x must be negative
    

    with/as Context Managers

    The with/as statement is designed to be an alternative to a common try/finally usage idiom.

    Basic Usage

    with expression [as variable]:
         with-block
    

    The expression here is assumed to return an object that supports the context management protocol. (Usually file). It closes the file like finally.

    • The object returned by the expression may then run startup code before the with-block is started, as well as termination code after the block is done, regardless of whether the block raised an exception or not.
    • two examples
      operate a file:
    with open(r'c:\misc\data') as myfile:
        for line in myfile:
            print(line)
            more code...
    
    • thread lock
    # The context management machinery guarantees that the lock is automatically acquired before the block is executed and released once the block is complete.
    lock = threading.Lock()
    with lock:
        ...access shared resources...
    
    • set decimal precision
    with decimal.localcontext() as ctx:
        ctx.prec = 2
        x = decimal.Decimal('1.00') / decimal.Decimal('3.00')
    

    After this statement runs, the current thread's context manager state is automatically restored to what it was before the statement began.

    The Context Management Protocol

    • How the with statement actually works:
    1. The expression is evaluated, resulting in an object known as a context manager that must have enter and exit methods.
    2. The context manager's enter method is called. The value it returns is assigned to the variable in the as clause if present, or simply discarded otherwise.
    3. No matter whether the with block raises an exception, the exit will be called. The exception, if is raised, will assign the details in the type, value, traceback in the exit. These variables will be assigned to None otherwise.

    Multiple Context Managers in 3.1, 2.7, and later

    ...pass...

    相关文章

      网友评论

        本文标题:Chapter 34: Exception Coding Det

        本文链接:https://www.haomeiwen.com/subject/fyndyltx.html