美文网首页
The Python Tutorial -- Errors &

The Python Tutorial -- Errors &

作者: liaozb1996 | 来源:发表于2018-03-19 18:31 被阅读0次
import sys

try:
  SOME CODE
except (exception1, exception2):
  SOME CODE 
except EXCEPTION as err:
  print(err)
except:
  print('Error: ',  sys.exc_info()[0])
  raise
else:
  SOME CODE
finally:
  SOME CODE
errors.jpg

Errors 分为两种:语法错误和异常。

语法错误

>>> while True print('Hello world')  # while 后面少了 :
  File "<stdin>", line 1
    while True print('Hello world')
                   ^
SyntaxError: invalid syntax

出现了语法错误,只能回到源文件去将语法修正

异常

>>> 4 + spam*3
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'spam' is not defined

异常则可以通过 try 语句来处理;

Python 内建异常 Built-in Exceptions

异常处理

# 让用户不断输入,直到得到一个数字,或按 Ctrl-C 退出

>>> while True:
...     try:
...         x = int(input("Please enter a number: "))
...         break
...     except ValueError:
...         print("Oops!  That was no valid number.  Try again...")
...

用户按 Ctrl-C 会触发异常 KeyboardInterrupt

try 异常处理执行过程:

  • 执行 try 语句(位于 tryexcept 之间的语句)
    • 没有异常发生 --> 跳过 except 语句,并进行执行后面的语句
    • 一个异常发生 --> 跳过 try 中异常后面的语句
      • 如果发生的异常与 except 后面的异常批准,执行该 except 语句
      • 如果没有匹配的异常,则抛出该异常,如果没有外部其他 try 语句处理,程序中止,显示异常
try_clause.jpg

except 后面可以带多个 handlers

... except (RuntimeError, TypeError, NameError):
...     pass

子类(从父类中衍生出的类)的异常可以被父类捕捉

# 打印 B C D
class B(Exception):
    pass

class C(B):
    pass

class D(C):
    pass

for cls in [B, C, D]:
    try:
        raise cls()
    except D:   # 如果这三个 except 的顺序改成 B C D,将打印 B B B
        print("D")
    except C:
        print("C")
    except B:
        print("B")

最后一个 except 后面可以不带 handler/exception name,这样讲捕捉任何异常

慎用!因为这种做法可能会导致程序 bug 难以找出;更好的做法是打印出异常信息并再次抛出异常

import sys

try:
    f = open('myfile.txt')
    s = f.readline()
    i = int(s.strip())
except OSError as err:   # 注意只要有一个异常实例,可以打印出异常参数(信息)
    print("OS error: {0}".format(err))
except ValueError:
    print("Could not convert data to an integer.")
except:
    print("Unexpected error:", sys.exc_info()[0])
    raise

The except clause may specify a variable after the exception name. The variable is bound to an exception instance with the arguments stored in instance.args. For convenience, the exception instance defines __str__() so the arguments can be printed directly without having to reference .args. One may also instantiate an exception first before raising it and add any attributes to it as desired.

try...except 语句还可以带 else 语句; else 要位于所有 except 后面;当没有异常发生时,执行 else 语句

for arg in sys.argv[1:]:
    try:
        f = open(arg, 'r')
    except OSError:
        print('cannot open', arg)
    else:
        print(arg, 'has', len(f.readlines()), 'lines')
        f.close()

else 语句的代码适用于 try 语句必须正常执行后才能执行的代码(正常打开文件后,才打印文件内容);
不把 else 的代码放进 try 是要避免异常是由不是本意要保护的代码造成的

raise

raise 用于强制抛出异常;
raise 带的参数应是异常实例或 Exception 的子类;
如果后面带的是子类, Python 会隐含地初始化它: raise ValueError ==》 raise ValueError()

>>> raise NameError('HiThere')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: HiThere

或者再次抛出异常

>>> try:
...     raise NameError('HiThere')
... except NameError:
...     print('An exception flew by!')
...     raise
...
An exception flew by!
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
NameError: HiThere

用户自定义的异常

用户自定义异常就是定义定义直接或间接继承 Exception 的子类;
自定义的异常应尽可能的简单,仅包含所需要的异常参数;
如果一个模块包含多个异常,通常是先定义一个基础的异常,再衍生出其他具体的异常;

class Error(Exception):
    """Base class for exceptions in this module."""
    pass

class InputError(Error):
    """Exception raised for errors in the input.

    Attributes:
        expression -- input expression in which the error occurred
        message -- explanation of the error
    """

    def __init__(self, expression, message):
        self.expression = expression
        self.message = message

class TransitionError(Error):
    """Raised when an operation attempts a state transition that's not
    allowed.

    Attributes:
        previous -- state at beginning of transition
        next -- attempted new state
        message -- explanation of why the specific transition is not allowed
    """

    def __init__(self, previous, next, message):
        self.previous = previous
        self.next = next
        self.message = message
  • 大多数异常的名称都以 Error 结尾

Clean-up Actions 清理工作

try 语句还可以带另一个语句 -- finally,无论有没有异常发生,finally 都会执行。

>>> try:
...     raise KeyboardInterrupt
... finally:
...     print('Goodbye, world!')
...

Goodbye, world!
KeyboardInterrupt
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>

虽然 finally 语句可以用于释放资源(文件或网络连接),但是还有一种更好的方法就是使用 with

with open("myfile.txt") as f:
    for line in f:
        print(line, end="")

但代码块执行结束时,文件资源将自动释放;支持 with 语句的对象都会在文档表明

相关文章

网友评论

      本文标题:The Python Tutorial -- Errors &

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