Python 中(至少)有两种错误:语法错误(syntax errors)和异常(exceptions)。

语法错误

语法错误又称作解析错误:

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

语法分析器指出错误行,并且在检测到错误的位置前面显示^。

异常

即使语句或表达式在语法上是正确的,执行时也可能会引发错误。运行期检测到的错误称为异常

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

错误信息的最后一行指出发生了什么错误。异常也有不同的类型,异常类型做为错误信息的一部分显示出来:示例中的异常分别为 ZeroDivisionErrorNameError 和 TypeError。打印错误信息时,异常的类型作为异常的内置名显示。对于所有的内置异常都是如此,不过用户自定义异常就不一定了(尽管这是很有用的约定)。标准异常名是内置的标识符(非保留关键字)。

这行后一部分是关于该异常类型的详细说明,这意味着它的内容依赖于异常类型。

错误信息的前半部分以堆栈的形式列出异常发生的位置。通常在堆栈中列出了源代码行,然而,来自标准输入的源码不会显示出来。

内置的异常 列出了内置异常和它们的含义。

异常处理

例子:要求用户输入直到输入合法的整数为止,但允许用户中断这个程序(使用Control-C或系统支持的任何方法)。注意:用户产生的中断会引发 KeyboardInterrupt 异常。

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

try 语句按如下方式工作。

  • 首先,执行try和except 之间的内容
  • 如果没有异常发生,忽略except语句。
  • 如果在 try 子句执行过程中发生了异常,那么该子句其余的部分就会忽略。如果异常匹配于 * 后面指定的异常类型,就执行对应的except子句。然后继续执行try语句之后的代码。
  • 如果发生了一个异常,在except 子句中没有与之匹配的分支,它就会传递到上一级try 语句中。如果最终仍找不到对应的处理语句,它就成为未处理异常,终止程序运行,显示提示信息。

try语句可能包含多个 except 子句,分别指定处理不同的异常。至多执行一个分支。异常处理程序只会处理对应的 try 子句中发生的异常,在同一try语句中,其他子句中发生的异常则不作处理。except 子句可以在元组中列出多个异常的名字,例如:

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

异常匹配如果except子句中的类相同的类或其基类(反之如果是其子类则不行)。 例如,以下代码将按此顺序打印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:
print("D")
except C:
print("C")
except B:
print("B")

如果except B在先,将打印B,B,B。

最后except子句可以省略例外名称,作为通配符。 请谨慎使用此功能,因为这种方式很容易掩盖真正的编程错误! 它也可以用来打印错误消息,然后重新引发异常(也允许调用者处理异常):

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

try … except语句可以带有else子句,该子句只能出现在所有 except 子句之后。当 try 语句没有抛出异常时,需要执行一些代码,可以使用这个子句。例如:

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子句中附加代码要好,因为这样可以避免 try … except 意外的截获本来不属于它们的那些代码抛出的异常。

发生异常时,可能会有相关值,作为异常的参数存在。这个参数是否存在、是什么类型,依赖于异常的类型。

在异常名(元组)之后,也可以为 except 子句指定一个变量。这个变量绑定于异常实例,它存储在instance.args参数中。为了方便起见,异常实例定义了 str() ,这样就可以直接访问过打印参数而不必引用.args。也可以在引发异常之前初始化异常,并根据需要向其添加属性。

>>> try:
... raise Exception('spam', 'eggs')
... except Exception as inst:
... print(type(inst)) # the exception instance
... print(inst.args) # arguments stored in .args
... print(inst) # __str__ allows args to be printed directly,
... # but may be overridden in exception subclasses
... x, y = inst.args # unpack args
... print('x =', x)
... print('y =', y)
...
<class 'Exception'>
('spam', 'eggs')
('spam', 'eggs')
x = spam
y = eggs

对于那些未处理的异常,如果它们带有参数,那么就会被作为异常信息的最后部分(“详情”)打印出来。

异常处理器不仅仅处理那些在 try 子句中立刻发生的异常,也会处理那些 try 子句中调用的函数内部发生的异常。例如:

>>> try:
... raise Exception('spam', 'eggs')
... except Exception as inst:
... print(type(inst)) # the exception instance
... print(inst.args) # arguments stored in .args
... print(inst) # __str__ allows args to be printed directly,
... # but may be overridden in exception subclasses
... x, y = inst.args # unpack args
... print('x =', x)
... print('y =', y)
...
<class 'Exception'>
('spam', 'eggs')
('spam', 'eggs')
x = spam
y = eggs

抛出异常

raise 语句可强行抛出指定的异常。例如:

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

要抛出的异常由raise的唯一参数标识。它必需是异常实例或异常类(继承自 Exception 的类)。如果传递异常类,它将通过调用它的没有参数的构造函数而隐式实例化:

raise ValueError  # shorthand for 'raise ValueError()'

如果你想知道异常是否抛出,但不想处理它,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 <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” 结尾。

很多标准模块中都定义了自己的异常,以报告在他们所定义的函数中可能发生的错误。关于类的进一步信息请参见Classes。

定义清理行为

try 语句有可选的子句定义在任何情况下都一定要执行的清理操作。例如:

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

不管有没有发生异常,finally子句在程序离开try前都会被执行。当语句中发生了未捕获的异常(或者它发生在except或else子句中),在执行完finally子句后它会被重新抛出。 try语句经由break、continue或return语句退出也会执行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("", "")
executing finally clause
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in divide
TypeError: unsupported operand type(s) for /: 'str' and 'str'

finally子句多用于释放外部资源(文件或网络连接之类的)。

预定义清理行为

有些对象定义了标准的清理行为,无论对象操作是否成功,不再需要该对象的时候就会起作用。以下示例尝试打开文件并把内容输出到屏幕。

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

这段代码的问题在于在代码执行完后没有立即关闭打开的文件。简单的脚本里没什么,但是大型应用程序就会出问题。with语句使得文件之类的对象能及时准确地进行清理。

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

语句执行后,文件f总会被关闭,即使是在处理文件行时出错也一样。其它对象是否提供了预定义的清理行为要参考相关文档。

异常处理实例: 正则表达式及拼音排序

有某群的某段聊天记录

现在要求输出排序的qq名,结果类似如下:

[..., '本草隐士', 'jerryyu', '可怜的樱桃树', '叻风云', '欧阳-深圳白芒',  ...]

需求来源:有个想批量邀请某些qq群的活跃用户到自己的群。又不想铺天盖地去看聊天记录。

参考资料:python文本处理

参考代码:

#!/usr/bin/python3
# -*- coding: utf-8 -*-
# Author: xurongzhong@126.com wechat:pythontesting qq:37391319
# 技术支持 钉钉群:21745728(可以加钉钉pythontesting邀请加入)
# qq群:144081101 591302926 567351477
# CreateDate: 2018-6-1 import re
from pypinyin import lazy_pinyin name = r'test.txt' text = open(name,encoding='utf-8').read()
#print(text) results = re.findall(r'(:\d+)\s(.*?)\(\d+', text) names = set()
for item in results:
names.add(item[1]) keys = list(names)
keys = sorted(keys) def compare(char):
try:
result = lazy_pinyin(char)[0][0]
except Exception as e:
result = char
return result keys.sort(key=compare)
print(keys)

执行示例:

1,把qq群的聊天记录导出为txt格式,重命名为test.txt

2, 执行:

$ python3 qq.py
['Sally', '^^O^^', 'aa催乳师', 'bling', '本草隐士', '纯中药治疗阳痿早泄', '长夜无荒', '东方~慈航', '干金草', '广东-曾超庆', '红梅* 渝', 'jerryyu', '可怜的樱桃树', '叻风云', '欧阳-深圳白芒', '勝昔堂~元亨', '蜀中~眉豆。', '陕西渭南逸清阁*无为', '吴宁……任', '系统消息', '于立伟', '倚窗望岳', '烟霞霭霭', '燕子', '张强', '滋味', '✾买个罐头 吃西餐', '【大侠】好好', '【大侠】面向大海~纯中药治烫伤', '【宗师】吴宁……任', '【宗师】红梅* 渝', '【少侠】焚琴煮鹤', '【少侠】笨笨', '【掌门】溆浦☞山野人家']

参考资料

  • python测试等IT技术支持qq群: 887934385(后期会录制视频)

python3快速入门教程错误和异常的更多相关文章

  1. MongoDb 快速入门教程

    文章首发于[博客园-陈树义],点击跳转到原文MongoDb 快速入门教程. MongoDb 是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的. 它是可扩展的 ...

  2. MySQL 快速入门教程

    转:MySQL快速 入门教程 目录 一.MySQL的相关概念介绍 二.Windows下MySQL的配置 配置步骤 MySQL服务的启动.停止与卸载 三.MySQL脚本的基本组成 四.MySQL中的数据 ...

  3. npm 与 package.json 快速入门教程

    npm 与 package.json 快速入门教程 2017年08月02日 19:16:20 阅读数:33887 npm 是前端开发广泛使用的包管理工具,之前使用 Weex 时看了阮一峰前辈的文章了解 ...

  4. [转载]npm 与 package.json 快速入门教程

    npm 与 package.json 快速入门教程 2017-08-02 19:16:20 拭心 阅读数 78648更多 分类专栏: 学学前端   版权声明:本文为博主原创文章,遵循CC 4.0 BY ...

  5. 专为设计师而写的GitHub快速入门教程

    专为设计师而写的GitHub快速入门教程 来源: 伯乐在线 作者:Kevin Li     原文出处: Kevin Li 在互联网行业工作的想必都多多少少听说过GitHub的大名,除了是最大的开源项目 ...

  6. EntityFramework6 快速入门教程

    EntityFramework6 快速入门教程 不得不说EF在国内实在是太小众,相关的技术文章真实屈指可数,而且很多文章都很旧了,里面使用的版本跟如今的EF6差别还是比较大.我刚开始弄这个的时候真是绕 ...

  7. Apple Watch开发快速入门教程

     Apple Watch开发快速入门教程  试读下载地址:http://pan.baidu.com/s/1eQ8JdR0 介绍:苹果为Watch提供全新的开发框架WatchKit.本教程是国内第一本A ...

  8. 指示灯组与3个复位按钮的介绍Arduino Yun快速入门教程

    指示灯组与3个复位按钮的介绍Arduino Yun快速入门教程 1.4.2  指示灯组 指示灯组的放大图如图1.5所示. 图1.5  指示灯组 各个指示灯对应的功能如下: q  RX:对应于0号端口, ...

  9. 游戏控制杆OUYA游戏开发快速入门教程

    游戏控制杆OUYA游戏开发快速入门教程 1.2.2  游戏控制杆 游戏控制杆各个角度的视图,如图1-4所示,它的硬件规格是本文选自OUYA游戏开发快速入门教程大学霸: 图1-4  游戏控制杆各个角度的 ...

随机推荐

  1. 解决SpringBatch/Cloud Task的SafeMode下的报错问题

    问题描述 一般公司都有DBA,DBA极有可能开启了Safe mode,也就是不支持不带索引条件过滤的update操作. 而Spring Batch /Cloud Task就有一张表 JOB_SEQ或者 ...

  2. 基于Mustache实现sql拼接

    目录 一.前言 二.Mustache语法 三.Mustache拼接sql 一.前言 Mustache语法是一种模板语法,它可以帮我们拼接我们想要的东西.入职新公司,而项目里的sql语句就是用Musta ...

  3. nginx篇最初级用法之三种虚拟主机基于域名\基于端口\基于IP地址端口的虚拟主机

    在nginx中虚拟主机的类型与apache一样也有三种 1.基于域名的虚拟主机 2.基于端口的虚拟主机 3.基于IP地址端口的虚拟主机 在nginx配置文件中每一个server为一个虚拟主机如果需要多 ...

  4. 网络安全-主动信息收集篇第二章-二层网络扫描之arping

    arping二层网络发现 介绍工具:arping arping主要查看IP的MAC地址 缺点:工具本身只能ping一个IP地址,不能ping一个IP段.但是可以通过脚本将整个网络中的IP进行扫描. 脚 ...

  5. Redis实战--Redis整合SpringBoot示例

    echo编辑整理,欢迎转载,转载请声明文章来源.欢迎添加echo微信(微信号:t2421499075)交流学习. 百战不败,依不自称常胜,百败不颓,依能奋力前行.--这才是真正的堪称强大!!! 该文章 ...

  6. nmap学习笔记-扫描格式

    习惯性的前言: 之前曾经零零星星的学习过一段时间的nmap,但是因为用的少,后续有慢慢的放下了,这次正好借着工作上的机会重新学习一下nmap,并记录在此. nmap端口状态: open:应用程序在该端 ...

  7. FHQ treap学习(复习)笔记

    .....好吧....最后一篇学习笔记的flag它倒了..... 好吧,这篇笔记也鸽了好久好久了... 比赛前刷模板,才想着还是补个坑吧... FHQ,这个神仙(范浩强大佬),发明了这个神仙的数据结构 ...

  8. 用python实现对元素的长截图

    一.目标 浏览网页的时候,看见哪个元素,就能截取哪个元素当图片,不管那个元素有多长 二.所用工具和第三方库 python ,PIL,selenium pycharm 三.代码部分 长截图整体思路: 1 ...

  9. Scrapy简单上手 —— 安装与流程

    一.安装scrapy 由于scrapy依赖较多,建议使用虚拟环境 windows下pip安装(不推荐) 1.安装virtualenv pip install virtualenv 2.在你开始项目的文 ...

  10. jquery swiper3自定义切换效果的方法

    jquery swiper3自定义切换效果的方法 <pre> <div class="swiper-slide"> <div class=" ...