Python 错误和异常

作为 Python 初学者,在刚学习 Python 编程时,经常会看到一些报错信息,在前面我们没有提及,这章节我们会专门介绍。

Python 有两种错误很容易辨认:语法错误和异常。

语法错误

Python 的语法错误或者称之为解析错,是初学者经常碰到的,如下实例

>>>while True print('Hello world')
  File "<stdin>", line 1, in ?
    while True print('Hello world')
                   ^
SyntaxError: invalid syntax

这个例子中,函数 print() 被检查到有错误,是它前面缺少了一个冒号(:)。

语法分析器指出了出错的一行,并且在最先找到的错误的位置标记了一个小小的箭头。

异常

即便Python程序的语法是正确的,在运行它的时候,也有可能发生错误。运行期检测到的错误被称为异常。

大多数的异常都不会被程序处理,都以错误信息的形式展现在这里:

>>>10 * (1/0)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
ZeroDivisionError: division by zero
>>> 4 + spam*3
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
NameError: name 'spam' is not defined
>>> '2' + 2
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: Can't convert 'int' object to str implicitly

异常以不同的类型出现,这些类型都作为信息的一部分打印出来: 例子中的类型有 ZeroDivisionError,NameError 和 TypeError。

错误信息的前面部分显示了异常发生的上下文,并以调用栈的形式显示具体信息。

异常处理

以下例子中,让用户输入一个合法的整数,但是允许用户中断这个程序(使用 Control-C 或者操作系统提供的方法)。用户中断的信息会引发一个 KeyboardInterrupt 异常。

try语句按照如下方式工作;

  • 首先,执行try子句(在关键字try和关键字except之间的语句)
  • 如果没有异常发生,忽略except子句,try子句执行后结束。
  • 如果在执行try子句的过程中发生了异常,那么try子句余下的部分将被忽略。如果异常的类型和 except 之后的名称相符,那么对应的except子句将被执行。最后执行 try 语句之后的代码。
  • 如果一个异常没有与任何的except匹配,那么这个异常将会传递给上层的try中。

一个 try 语句可能包含多个except子句,分别来处理不同的特定的异常。最多只有一个分支会被执行。

处理程序将只针对对应的try子句中的异常进行处理,而不是其他的 try 的处理程序中的异常。

一个except子句可以同时处理多个异常,这些异常将被放在一个括号里成为一个元组,例如:

最后一个except子句可以忽略异常的名称,它将被当作通配符使用。你可以使用这种方法打印一个错误信息,然后再次把异常抛出。

try except 语句还有一个可选的else子句,如果使用这个子句,那么必须放在所有的except子句之后。这个子句将在try子句没有发生任何异常的时候执行。例如:

使用 else 子句比把所有的语句都放在 try 子句里面要好,这样可以避免一些意想不到的、而except又没有捕获的异常。

异常处理并不仅仅处理那些直接发生在try子句中的异常,而且还能处理子句中调用的函数(甚至间接调用的函数)里抛出的异常。例如:

>>>def this_fails():
        x = 1/0
  
>>> try:
        this_fails()
    except ZeroDivisionError as err:
        print('Handling run-time error:', err)
  
Handling run-time error: int division or modulo by zero

抛出异常

Python 使用 raise 语句抛出一个指定的异常。例如:

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

raise 唯一的一个参数指定了要被抛出的异常。它必须是一个异常的实例或者是异常的类(也就是 Exception 的子类)。

如果你只想知道这是否抛出了一个异常,并不想去处理它,那么一个简单的 raise 语句就可以再次把它抛出。

>>>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 ?
NameError: HiThere

用户自定义异常

你可以通过创建一个新的异常类来拥有自己的异常。异常类继承自 Exception 类,可以直接继承,或者间接继承,例如:

>>>class MyError(Exception):
        def __init__(self, value):
            self.value = value
        def __str__(self):
            return repr(self.value)
  
>>> try:
        raise MyError(2*2)
    except MyError as e:
        print('My exception occurred, value:', e.value)
  
My exception occurred, value: 4
>>> raise MyError('oops!')
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
__main__.MyError: 'oops!'

在这个例子中,类 Exception 默认的 __init__() 被覆盖。

<p异常的类可以像其他的类一样做任何事情,但是通常都会比较简单,只提供一些错误相关的属性,并且允许处理异常的代码方便的获取这些信息。< p="">

当创建一个模块有可能抛出多种不同的异常时,一种通常的做法是为这个包建立一个基础异常类,然后基于这个基础类为不同的错误情况创建不同的子类:

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"结尾,就跟标准的异常命名一样。


定义清理行为

try 语句还有另外一个可选的子句,它定义了无论在任何情况下都会执行的清理行为。 例如:

>>>try: ... raise KeyboardInterrupt ... finally: ... print('Goodbye, world!') ... Goodbye, world! Traceback (most recent call last): File "<stdin>", line 2, in <module> KeyboardInterrupt

以上例子不管 try 子句里面有没有发生异常,finally 子句都会执行。

如果一个异常在 try 子句里(或者在 except 和 else 子句里)被抛出,而又没有任何的 except 把它截住,那么这个异常会在 finally 子句执行后被抛出。

下面是一个更加复杂的例子(在同一个 try 语句里包含 except 和 finally 子句):

>>>def divide(x, y): try: result = x / y except ZeroDivisionError: print("division by zero!") else: print("result is", result) finally: print("executing finally clause") >>> divide(2, 1) result is 2.0 executing finally clause >>> divide(2, 0) division by zero! executing finally clause >>> divide("2", "1") executing finally clause Traceback (most recent call last): File "<stdin>", line 1, in ? File "<stdin>", line 3, in divide TypeError: unsupported operand type(s) for /: 'str' and 'str'

预定义的清理行为

一些对象定义了标准的清理行为,无论系统是否成功的使用了它,一旦不需要它了,那么这个标准的清理行为就会执行。

这面这个例子展示了尝试打开一个文件,然后把内容打印到屏幕上:

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

以上这段代码的问题是,当执行完毕后,文件会保持打开状态,并没有被关闭。

关键词 with 语句就可以保证诸如文件之类的对象在使用完之后一定会正确的执行他的清理方法:

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

以上这段代码执行完毕后,就算在处理过程中出问题了,文件 f 总是会关闭。

参考资料

Python - 错误和异常 - 第十九天的更多相关文章

  1. Python错误和异常概念(总)

    转载请标明出处: http://www.cnblogs.com/why168888/p/6435956.html 本文出自:[Edwin博客园] Python错误和异常概念(总) 1. 错误和异常的处 ...

  2. Python错误和异常学习

    一:错误解释 1.语法错误:代码不符合解释器或者编译器语法 2.逻辑错误:不完整或者不合法输入或者计算出现问题 代码运行前的语法或者逻辑错误,语法错误在执行前修改,逻辑错误无法修改 二:异常 执行过程 ...

  3. 13.python错误和异常

    一.错误和异常1.程序中的错误分为俩种:(1)语法错误:不按照语言的规则,必须在程序执行前就改正(2)逻辑错误2.异常就是程序运行时发生错误的信号,分为三部分(1)Traceback:异常追踪的信息( ...

  4. Python错误和异常 学习笔记

    错误和异常概念 错误:     1.语法错误:代码不符合解释器或者编译器语法     2.逻辑错误:不完整或者不合法输入或者计算出现问题 异常:执行过程中出现万体导致程序无法执行     1.程序遇到 ...

  5. Python错误与异常

    1 异常和错误 1.1 错误和异常 从软件方面来说,错误是语法或者逻辑上的,语法错误指示软件的结构上有错误,导致不能被解释器解释.当程序的语法正确后,剩下的就是逻辑错误了,逻辑错误可能是由于不完整或者 ...

  6. Python 错误和异常

    1.Python异常类 Python是面向对象语言,所以程序抛出的异常也是类.常见的Python异常有以下几个,大家只要大致扫一眼,有个映像,等到编程的时候,相信大家肯定会不只一次跟他们照面(除非你不 ...

  7. python错误和异常

    一:语法错误syntax errors        熟悉语法! 二:异常 ①打印错误信息时,异常的类型作为异常的内置名显示,并以调用栈的形式显示具体信息    ②常见的异常:             ...

  8. Python 错误和异常小结[转]

    原文链接    http://blog.csdn.net/sinchb/article/details/8392827 事先说明哦,这不是一篇关于Python异常的全面介绍的文章,这只是在学习Pyth ...

  9. Python 错误和异常小结

    1.Python异常类 Python是面向对象语言,所以程序抛出的异常也是类.常见的Python异常有以下几个,大家只要大致扫一眼,有个映像,等到编程的时候,相信大家肯定会不只一次跟他们照面(除非你不 ...

随机推荐

  1. spring web mvc环境搭建

    这两天在学习spring,哎,没办法呀,成都基本都是java,不喜欢学这个也没有用.多学点多条路.还得生活不是. 好了,言归正传,我这里记录下我搭建spring mvc的过程,其实过程不算太难,主要是 ...

  2. uni-app自定义导航栏按钮|uniapp仿微信顶部导航条

    最近一直在学习uni-app开发,由于uniapp是基于vue.js技术开发的,只要你熟悉vue,基本上很快就能上手了. 在开发中发现uni-app原生导航栏也能实现一些顶部自定义按钮+搜索框,只需在 ...

  3. 记录MySql错误消息

    本章列出了当你用任何主机语言调用MySQL时可能出现的错误.首先列出了服务器错误消息.其次列出了客户端程序消息. B.. 服务器错误代码和消息 服务器错误信息来自下述源文件: · 错误消息信息列在sh ...

  4. Linux—网络防火墙详解

    一.防火墙基本知识 二.firewall防火墙 # 安装firewalld [root@localhost ~]# apt-get install firewalld [root@localhost ...

  5. c++ 模板特化与局部特化

    c++ 模板特化与局部特化 模板的由来是要处理泛化,也就是任何类型都可以处理.但是泛化的同时,如果针对某种特殊的类型,又更加效率的处理方法.c++提供针对特殊的类型,可以定义不同的处理方法.针对某种特 ...

  6. weblogic(一).简介与安装

    weblogic(一).简介与安装   WebLogic是美国Oracle公司出品的一个application server,确切的说是一个基于JAVAEE架构的中间件,WebLogic是用于开发.集 ...

  7. 1.Python网络编程_UDP(简略版)

    # -*- coding: utf-8 -*- #2019-11-24 import socket def recv(): udp_socket=socket.socket(socket.AF_INE ...

  8. 3.Python爬虫入门_正则表达式(简单例子)

    #2019-11-23 import requests import time import re #Python正则表达式库 if __name__=='__main__': #海量爬取图片数据 # ...

  9. while语句 break和continue

    1.whlie 循环 基本条件 :while 条件: 代码块(循环体) else: 当上面的条件为假的,才会执行 执行顺序: 判断条件是否为真,如果为真,执行循环体,然后判断条件,...直到循环条件为 ...

  10. -shared -fPIC

    gcc -shared -fPIC -o 1.so 1.c   这里有一个-fPIC参数 PIC就是position independent code PIC使.so文件的代码段变为真正意义上的共享