异常
什么是异常?
异常即是一个事件,该事件会在程序执行过程中发生,影响了程序的正常执行。
当Python脚本发生异常时我们需要捕获处理它,否则程序会终止执行。
常见的异常:
除0错误:ZeroDivisionError
未声明变量: NameError
索引异常: IndexError
字典key值错误: KeyError
缩进异常: IndentationError
输入/输出错误:IOError
检测和处理异常
异常可以通过 try 语句来检测。任何在 try 语句块里的代码都会被监测,检查有无异常发生。
try 语句有两种主要形式: try-except 和 try-finally . 这两个语句是互斥的, 也就是说你只 能 使 用 其 中 的 一 种 . 一 个 try 语 句 可 以 对 应 一 个 或 多 个 except 子 句 , 但 只 能 对 应 一 个 finally 子句, 或是一个 try-except-finally 复合语句.
try-except 语句
try:
print(s)
print(5/0)
except:
# try里面的代码如果有异常/错误, 才会执行的代码;
print("报错")
else:
# 判断是否有异常, 如果没有, 执行此代码;
print("运行成功")
finally:
# 有异常和没有异常都会执行的代码;
print("检测finally的作用")
我们try里面有两个错误NameError和ZeroDivisionError
这样运行执行的是except里面的内容。
else 子句
我们已经看过 else 语句段配合其他的 Python 语句,比如条件和循环。至于 try-except 语句段,它的功能和你所见过的其他 else 没有太多的不同:在 try 范围中没有异常被检测到时,执行 else 子句。
finally 子句
finally 子句是无论异常是否发生,是否捕捉都会执行的一段代码。你可以将 finally 仅仅配合 try 一起使用,也可以和 try-except(else 也是可选的) 一起使用,也可以使用独立的 try-finally
带有多个 except 的 try 语句
这种格式的 except 语句指定检测名的异常. 你可以把多个 except 语句连接在一起, 处理一个 try 块中可能发生的多种异常
import sys
try:
10/0
f = open('passwd')
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(sys.exc_info())
print("Unexpected error:", sys.exc_info()[0])
触发异常
raise语句
raise 语句对所支持是参数十分灵活,对应到语法上就是支持许多不同的格式.rasie 一般的用法是:
raise [Exception [, args [, traceback]]]
语句中 Exception 是异常的类型(例如,NameError)参数标准异常中任一种,
args 是自已提供的异常参数。
抛出异常
name = input("姓名:")
if len(name) < 2:
raise NameError("姓名必须大于2位") #如果姓名少于一位,主动抛出异常
age = int(input("年龄:"))
if age < 0 or age >= 120:
raise NameError("年龄必须在0<age<150") #如果年龄不在0~120岁之间,主动抛出异常
异常处理实例:
我们做一个动图反转的小案例
# ImageSequence: 会将动图分割成每一帧的图片;
import os
from PIL import Image, ImageSequence
def gif_reverse(src_file, dst_file):
"""
实现动图的反转
:param src_file:
:param dst_file:
:return:
"""
try:
# 打开文件, 并起一个别im
with Image.open(src_file) as im:
# 判断图片文件是否为动图?
if im.is_animated:
# 对于图片进行反转
images = [image.copy() for image in ImageSequence.Iterator(im)][::-1]
# 将反转的图片保存成新的动图;
images[0].save(dst_file, save_all=True, append_images=images[1:])
except BaseException as e:
print("动图反转错误:" , e)
else:
print("[%s] 反转为 [%s]成功!" %(src_file, dst_file))
def gif_split(src_file, dst_dirname):
"""
将gif动图分割为一个个图片
:param src_file: 分割的gif文件
:param dst_dirname: 存储图片的目录
"""
try:
# 打开文件, 并起一个别im
with Image.open(src_file) as im:
# 判断图片文件是否为动图?
if im.is_animated:
# 依次将动图的每个图片保存到文件中;
index = 0
for image in ImageSequence.Iterator(im):
# 获取存储文件的绝对路径;
filename = '%s.png' %(index)
full_filename = os.path.join(dst_dirname, filename)
image.save(filename)
index += 1
except BaseException as e:
print("动图分割失败: ", e)
else:
print("动图分割成功, 保存在[%s]目录中" %(dst_dirname))
if __name__ == '__main__':
gif_reverse('doc/timg.gif', 'doc/timg1.gif')
接着我们将这个做成一个模块
首先我们将上边的代码写到一个gif.py文件里
然后setup.py文件里写入
from distutils.core import setup
setup(
name='gif',
version='0.0.1',
py_modules = ['gif'],
author='lvah',
author_email='gf_guofan@163.com',
url='http://www.lvah.com',
description='动图的快速分割与反转'
)