第一节:关于Python
Python的诞生
1990年由
新西兰
人Guido van Rossum所创建,起名源于英国戏剧“Monty Python’s flying circus”;
主要版本有Python2和Python3,后者并不兼容前者,一些主流的框架已放弃对Python2的支持;
Python的特点
- 简洁优美,易于学习,因此受到热捧,并且广泛被作为编程的入门语言使用;
- 胶水语言,由于其简洁的特性和受追捧的程度,C和Java都为其提供了大量的类库支持,使得一个以Python为主要编程语言的工程,可以引入和调用大量C以及Java的类库,因此Python被称为是“胶水语言”;
- 面向对象,Python是面向对象的语言;
- 脚本语言,Python是一门脚本语言,由Python解释器逐行解释并执行;
有哪些运用领域?
- Web开发;
- 爬虫程序开发;
- 数据挖掘;
- 机器学习(人工智能);
- 少儿编程;
由于有C类库的支持,理论上Python是可以做任何事情的
第二节:Python的开发环境
Python解释器
当我们编写Python代码时,我们得到的是一个包含Python代码的以
.py
为扩展名的文本文件。要运行代码,就需要Python解释器去执行xxx.py
文件。解释这些代码,执行代码的运行。
Python解释器下载和安装
官方解释器下载地址:https://www.python.org/downloads/windows/
使用Python首先我们要接触Python的解释器,这里我们选择一个Python3的版本进行安装,Python2已经逐渐过时,这里不做讨论;
按照流程进行安装,安装过程中注意勾选【将python解释器路径添加到系统环境变量的选项】(也可以安装完成后手动将python.exe所在的路径);
api-ms-win-crt-process-l1-1-0.dll 丢失处理的解决方案
在安装Python3.6之后的版本,可能会提示api-ms-win-crt-process-l1-1-0.dll丢失的问题,导致一些软件或游戏无法正常运行。这是因为Windows Update更新问题导致,其中两个更新的编号为KB2999226(10.0.10240.16390)和KB3118401(10.0.10586.9)有问题。
解决方案:
到micorsoft 官网下载相应更新,再安装。重启后OK了。以下是两个下载链接,下载时选择自己电脑的系统类型和系统版本就可以了(查看“我的电脑-属性”)
KB2999226、KB3118401更新下载:
在cmd命令行中进行编程
如在正常成功安装了,那么可以在任意位置打开命令行,执行python命令,即输入
Python
,即可进入python编程环境;
输入代码print("hello world!")
,可以发现命令行立即进行了输出;
例:
使用释器解释并执行HelloWorld程序
- 在桌面建立hello.py文件,代码如下:
import time
print("hello world!")
time.sleep(3) #睡眠3秒
print("hello china!")
- 在桌面shift+右键,打开cmd命令窗口,执行命令:
python hello.py
,就会神奇地发现,命令窗口输出“hello world!”,3秒后再输出”hello china!”
使用python解释器进行编程
除了CMD,也可以直接使用python解释器进行编程,方法同上
集成开发环境
python的 IDLE
IDLE 是一个纯 Python 下自带的简洁的集成开发环境,具备基本的IDE的功能,当安装好python以后,IDLE就自动安装好了,不需要另外去找。
1、Python shell
启动IDLE就是一个Python shell,我们通过它可以在IDLE内部执行Python命令 ,利用IDLE这个shell就可以与Python的进行互动。
2、python编辑器
Python shell界面按Ctrl+N就会出现python编辑器,可以随意修改代码并保存
集成开发环境PyCharm
目前,python的集成开发环境非常多,很多也很好用,个人推荐合使用
pyCharm
,因为它是目前最流行的Python集成开发环境;
官方下载地址:http://www.jetbrains.com/pycharm/download/previous.html
按照流程指引进行安装;
安装完后,配置Python解释器位置;
在PyCharm中运行HelloWorld程序
刚才我们试过了运用CMD执行了HelloWorld程序,那么现在尝试使用Pycham执行HelloWorld程序
- 创建Pure Python工程,指定名称;
- 在工程中按需创建子目录并新建Python代码文件"HelloWorld.py"
- 插入代码
import time
print("Hello PyCharm!")
time.sleep(3)
print("Hello IDE!")
- 右键执行run HelloWorld;
- 执行结果如图
第三节:Python的基础程序设计
标识符
标识符的要点:
-
标识符是用来对常量、变量、方法、类、模块进行命名的字符;
-
标识符可以是大小写字母、数字、下划线;
-
命名不能以数字开头;
-
区分大小写;
-
命名风格可以是:
√ 驼峰风格
√ 小写字母+下划线风格例如:
# 小写字母+下划线风格的变量定义
the_radius_1 = 10
# 驼峰风格的变量定义
theRadius2 = 10
# 小写字母+下划线风格的方法定义
def get_circle_area_1(r):
return 3.14 * r * r
# 驼峰风格的方法定义
def getCircleArea2(r):
return 3.14 * r * r
常量、变量、表达式
- 常量的值不会发生变化,比如圆周率;
- 变量是值可以动态变化的量;
- 表达式是对常量和变量进行数学或逻辑运算的式子;
- 在Python中,我们可以使用一条语句给多个变量赋值;
# 定义常量,一般是全大写
PI = 3.14
# 定义变量,其值是可以动态改变的
radius = 10
# 使用表达式为变量area赋值
area = PI * radius * radius
print("半径变量改变前圆的面积是", area)
# 变量的值是可以动态改变的
radius = 20
area = PI * radius * radius
print("半径变量改变后圆的面积是", area)
# 同时给多个变量赋值
name, age = "Pythoner", 18
print(name, age)
执行结果:
基本数据类型
Python基本数据类型有如下7种:
int
—— 整型;
float
—— 浮点型;
complex
—— 复数类型;
bool
—— 布尔类型,取值可以是True或False,分别等于整型的1和0;
str
—— 字符串类型;
对象型
—— 类的实例;
None
—— NoneType类型
# 整型
intVar = 12
print(type(intVar))
# 浮点型
floatVar = 12.0
print(type(floatVar))
# 复数类型
complexVar = 12 + 34j
print(type(complexVar))
# 布尔类型
boolVar = True
print(type(boolVar))
# 字符串类型
strVar = "人生苦短,请用Python"
print(type(strVar))
# 对象类型
objVar = Canvas()
print(type(objVar))
# 空类型
noneVar = None
print(type(noneVar))
代码执行结果:
复数
- 复数表示
√ 基本表示:1 + 2j 或 complex(1,2),其中1为实部,2j为虚部;
√ 几何表达:
a + bj相当于直角坐标系中的(a,b)
用于表示复数的平面称为【复数平面】
√ 实数与虚数
实数:虚部为0的复数
虚数:虚部不为0的复数
纯虚数:实部为0而虚部不为0的复数
- 运算公式
√ (a+bi)+(c+di)=(a+c)+(b+d)i
√ (a+bi)-(c+di)=(a-c)+(b-d)i
√ (a+bi)*(c+di)=(ac-bd)+(ad+bc)i
√ (a+bi)/(c+di)=(a+bi)(c-di)/(c2+d2)
√ |a+bi|=(a2+b2)^0.5
- 复数的意义
√ 实数成为复数的子集,拓展了数的范围;
√ 平面几何(坐标)的代数表达;
√ 在各种物理和科学计算中应用广泛;
比如:
# 复数的两种定义形式
a = 1 + 2j
b = complex(3, 4)
# 复数的计算
print(a + b)
print(a - b)
print(a * b)
print(a / b)
print(abs(a))
执行结果:
注释与引号
前言:
为什么要有注释?注释是一段代码或一行代码的解释说明,便于可读性,理解性、执行性、必要性
- 单行注释与多行注释
单行注释通常在说明前用#
表示,并且不会出现在代码执行结果中,不会对代码产生影响 ,
多行注释通常在一段代码的前、后使用'''
表示,意为中间的多行,不会出现在代码执行结果中,仅做注释用
#我是单行注释
'''
我是多行注释
我是多行注释
我是多行注释
重要的事情说多几遍
'''
- 单引号、双引号、三引号的区别
例 如:
sentence = '我是单引号,单独使用时,我跟双引号没什么区别'
print(sentence)
sentence = "我是双引号,单独使用时,我跟单引号没什么区别"
print(sentence)
# 单引号内只能嵌套双引号
sentence = "毛主席说过:'一切反动派都是纸老虎'"
print(sentence)
# 双引号内只能嵌套单引号
sentence = '邓小平说过:"黑猫白猫,能抓住老鼠就是好猫"'
print(sentence)
# 三引号的格式在打印时会被保留
sentence = '''
一首好诗
大海啊你全他妈是水,
蜘蛛啊你全他妈是腿,
辣椒啊真他妈辣嘴,
不学Python啊真他妈后悔。
——亚洲气质舞王 尼古拉斯·赵四
'''
print(sentence)
执行结果:
程序错误
程序错误通常分为3类:
- 语法错误,——无法被解释器解释,比如引号没有成对出现;
# 语法错误在IDE中会立刻报红色不能执行结果,
print("不小必少了右边的引号)
语法错误在IDE中会立刻报红,在普通文本编辑工具中则难以发现,但解释器无法对其进行解释;
- 运行时错误,——语法正确,但解释时会报错,运行时错误又称为异常,常见的如零分母异常,类型异常等
# 这里会报一个零分母异常,因为零不能做除数
print(5/0)
执行结果:
# 这里会报一个类型异常,因为字符串是无法与浮点数进行计算的
a = "3"
print(a*3.14)
- 逻辑错误,——语法上没有错,也没有运行时异常,不会报错,纯粹只是业务逻辑不正确
# 这里是一个逻辑错误
radius = 10
area = 3.14 + radius
print("以10为半径的圆的面积是",area)
转义字符、占位符
-
转义字符
-
占位符
整型占位符:%d
;
浮点型占位符:%f
;
字符串占位符:%s
;
空白占位符:{}
,可以填充任意类型的数值;
序号占位符:{具体序号}
,参数列表会按序号的位置进行一一对应;
# 使用具体类型占位符
print("我的名字是%s,今年%d岁了,我的银行账户余额为%f"%("比尔",50,1234567890.123))
# 使用空白占位符
print("我的名字是{},今年{}岁了,我的银行账户余额为{}".format("比尔",50,1234567890.123))
# 使用序号占位符,这里注意,3个参数会依次对应到0、1、2的位置上
# 0号位置应填余额,1号位置应填年龄,2号位置应填姓名,因此正确的参数顺序为(1234567890.123,50,"比尔")
print("我的名字是{2},今年{1}岁了,我的银行账户余额为{0}".format(1234567890.123,50,"比尔"))
执行结果:
- 更多占位符
数学运算
- 加减乘除
print(2 + 3)
print(2 - 3)
print(2 * 3)
print(2 / 3)
- 整除、求余
print(10 // 4) # 整除
print(10 % 4) # 求余
- 求绝对值、最大、最小值
print(abs(-5)) # 【内建函数】abs()
print(math.fabs(-5)) # 通过math模块的fabs()求绝对值,带小数
print(max(12, 34, -56, 0))
print(min(12, 34, -56, 0))
- 四舍五入
print(round(3.4)) # 3
print(round(3.5)) # 4
# 负数按绝对值大小四舍五入
print(round(-3.4)) # -3
print(round(-3.5)) # -4
print(math.floor(3.9)) # 3
print(math.ceil(3.1)) # 4
- 角度的正弦、余弦、正切
print(math.sin(math.pi / 6))
print(math.cos(math.pi / 6))
print(math.tan(math.pi / 6))
- 角度、弧度互转
print(math.radians(30)) # 角度转弧度
print(math.degrees(math.pi / 6)) # 弧度转角度
- 乘方和开方
print(2 ** 3) # 2的3次幂
print(pow(2, 3)) # 2的3次幂
print(math.pow(2, 3)) # 2的3次幂,精度较高
print(math.sqrt(9)) # 9的开方
print(8 ** (1 / 3)) # 8开3次方,将开方转化为乘方
- 求对数
print(math.log(8, 2))
print(math.log(math.e ** 2)) # 默认底数为e
- 科学计数法
1.23E2或1.23E+2=1.23*10^2
1.23E-2=1.23*10^-2
- 自增强
temp = 5
temp += 3 # 自加3,等价于:temp = temp+3
temp -= 3
temp *= 3
temp /= 3
temp //= 3
temp %= 3
temp **= 3
print(temp)
**PS:**算术运算符的优先级:(括幂乘加法则)
括号最高
幂(乘方,指数)
乘除(包括整除和求余)
加减
用input
接收用户输入
-
接收用户输入的单个值
需要注意的是,用户输入的任何值,都会被视为一个
字符串
;
如果要参与数学计算,务必要先将其类型转换为数值型;
radius = input("请输入您的头的半径:") # input函数接收的任何输入均为字符串类型
print("您的头的半径为", radius)
# area = 3.14 * radius * radius #类型错误
print("radius的类型为:", type(radius)) # 字符串类型(str),而非数值类型
# 只有数值类型才能进行数学计算
radiusStr = input("请输入您的头的半径:")
# 将字符串转化为数值,重新赋值给radius
radius = eval(radiusStr)
print("radius的类型为:", type(radius)) # 整数类型(int)
# 计算结果
area = 3.14 * radius * radius
print("您的脸有:", area, "那么大")
执行结果:
-
一次性接收用户输入的多个值
用户在输入时,值之间需要使用英文逗号’
,
'进行分隔;
input方法外部必须使用eval方法包裹,否则用户输入的数据只会被视为一个普通字符串;
# 注意使用eval方法将多个值进行转化
width, height = eval(input("请输入矩形宽高:"))
print("width的类型为", type(width), "width=", width)
print("height的类型为", type(height), "height=", height)
print("矩形的面积为:", width * height, "平米")
# 注意使用eval方法将多个值进行转化
a, b, c = eval(input("请输入三个值:"))
iMax = max(a, b, c)
iMin = min(a, b, c)
print("最大的值为:", iMax, "最小值为:", iMin)
执行结果:
多样化的输出
- 精确保留小数位数
print("9876543210")
#format,表示格式化的意思,10.2f表示指定10宽度,2精度的格式化
print(format(3.1415926, ".2f"))
print(format(3.1415926, "10.2f"))
- 以百分号和科学计数法输出
print(format(9876543210, "10.2e")) # 用科学计数法表示
print(format(0.0000000123456789, "10.2e")) # 用科学计数法表示
print(format(0.56789, "10.2%"))
- 左右对齐输出
print(format(12.34567, "<20.2f"))
print(format(1234567890.12345, "<20.2f"))
print(format(12.34567, ">20.2f"))
print(format(1234567890.12345, ">20.2f"))
- 以不同进制进行输出
print(format(12345,"20b"))
print(format(12345,"20o"))
print(format(12345,"20d"))
print(format(12345,"20x"))
- 定义字符串的输出长度和对其方式
print(format("Hello","10s"))
print(format("Python","10s"))
print(format("Hello",">10s"))
print(format("Python",">10s"))
- 定义输出的结束符
print("悔创阿里杰克马",end='\t')
print("一无所有王健林",end='\t')
print("不识妻美刘强东",end='\t')
print("普通家庭马化腾",end='\n')
- 定义多个输出的分隔符
print("悔创阿里杰克马","一无所有王健林",sep=' & ',end=";")
print("不识妻美刘强东","普通家庭马化腾",sep=' & ')
- 输出格式化的文本
print('''
一首好诗
大海啊你全他妈是水,
蜘蛛啊你全他妈是腿,
辣椒啊真他妈辣嘴,
不学Python啊真他妈后悔。
——亚洲气质舞王 尼古拉斯·赵四
''')
- 输出引号本身
print("毛主席说过:'一切反动派都是纸老虎'")
print('邓小平说过:"黑猫白猫,能抓住老鼠就是好猫"')
print("赵四说过:\"这世上没有什么事情是一顿烧烤所不能解决的,如果有,那就两顿\"")
系统内建函数与关键字
系统的内建函数
内建函数的使用,不需要引入模块,直接调用;所有的内建函数存在于系统标准库模块builtin.py中;系统内建函数有很多,这里列举一些常用的
id()
—— 获取目标的内存地址
a = 10
arg1 = 4
arg2 = 6
b = arg1 + arg2
print("a/b", id(a), id(b))
print("两个变量指向相同的数值存储地址\n")
s = "helloworld"
arg1 = "hello"
arg2 = "world"
news = arg1 + arg2
print("s/news", id(s), id(news))
print("字符串拼接结果使用新的地址进行存储\n")
arg1 = 5
print("arg1", id(arg1))
arg1 = 6
print("arg1", id(arg1))
print("同一变量先后指向不同的内存地址")
def sayHello():
print("hello")
print("函数地址", id(sayHello))
format()
—— 格式化函数
# 参数1=要格式化的目标,参数2=格式
s = format(123.456, ".2f")
print(s, type(s)) # 123.46 <class 'str'>
- 数学计算函数
比如:
求最大值:max()
求最小值:min()
求绝对值:abs()
求幂:pow()
四舍五入:round()
print(max(1, 2))
print(min(1, 2))
print(abs(-1.2))
print(pow(2, 3)) # 8
print(round(-4.6)) # -5
- 类型与转换函数
获取目标的数据类型:
type()
取整或字符串转整型:int()
数值转字符串:str()
转换用户的输入为非字符串:eval()
print(type("hello")) # <class 'str'>
print(int("123"), int(123.45)) # 123 123
print(str(123.45), type(str(123.45))) # 123.45 <class 'str'>
print(eval("1,2,3"), type(eval("1,2,3"))) # (1, 2, 3) <class 'tuple'>
- 输入输出函数
输入函数:
input()
输出函数:print()
系统的内建函数还有许多,常用的还有:
系统关键字
python中一些具有特殊功能的标示符,就是所谓的【关键字】,它是python已经使用了的,所以不允许开发者自己定义和关键字相同的名字的标示符
- 常用的系统关键字
例如:
设置Pycham快捷键
- 常用的快捷键(Eclipse)
ctrl
+alt
+↓
——向下复制
ctrl
+d
——删除当前行
ctrl
+alt
+l
——格式化代码
ctrl
+/
——注释
ctrl
+z
——撤消上一步操作
ctrl
+y
——解撤消
ctrl
+F
——快速查找
ctrl
+shift
+/
(小键盤) ——折叠所有
ctrl
+*
(小键盤) ——展开所有
ctrl
+alt
+t
——快速包裹
ctrl
+alt
+p
——抽取选区为参数
alt
+↑
或↓
——移动选区
alt
+shift
+r
——重命名变量或函数
alt
+Enter
——生成解决方案
alt
+Insert
——插入覆写方法
alt
+left
/right
——光标回到上次位置
-
风格设置
File → Settings → Keymap → Eclipse风格(非默认风格) → 确定
-
自定义修改快捷键
可添加、修改、删除(推存直接添加)
第四节:字符集
什么是字符集
计算机记录文本的方式是通过字符集序号来记录的;
每一个字符的存储,都是以其位于字符集中的序号来实现的,包括空格、换行符、标点等;
最早的字符集是ASCII
,只包含包括大小写字母、阿拉伯数字、一些基本符号;
随着计算机在全球各国的普及,由于世界的语言众多,就诞生了各种适应不同语种的字符集;
专门适应中文的字符集有GBK、GB2312等,例如Windows操作系统中文版所使用的就是GBK字符集;
但无论何种字符集,都默认将ASCII完整包含在前128位当中;
由于不同主机中使用的字符集不同,导致了严重的数据传输乱码问题;
UTF-8字符集包含了世界各种不同语言中的常用字符,正逐渐成为某种意义上的、心照不宣的业界标准;
ASCII字符集
美国标准信息交换码(American Standard Code for Information Interchange);
包括最基本的128个字符,是最早也最基本的字符集;
内容包括大小写字母、阿拉伯数字、以及一些常用符号;
序号和字符的互换可以使用chr(order)和ord(character)两个系统内建函数;
ASCII码表
第五节:Python标准库使用案例
使用turtle绘制奥林匹克五环
标准库是系统自带的可用,为了体验其作用,使用标准库的API,在本节中,我们将以海龟库为例子。它可以使用编写简短的、简单的程序来创建漂亮的、甚至复杂的视觉效果。在海龟作图中,我们可以编写指令让一个虚拟的(想象中的)海龟在屏幕上来回移动。
ps:
1、如果是用pycharm,它和turtle库会有冲突,不能自己识别出turtle,API会报黄色警告,但不影响运行(其他解释器忽略此处)
2、海龟有两支画笔,一支是turtle,一支是turtle.Pen(),以下以turtle为例
- turtle模块常用API
showturtle() —— 显示窗口
penup()/pendown() —— 提起/落下画笔
left(90)/right(90) —— 向左转/向右转,参数为角度
goto(x,y) —— 移动画笔到指定位置
forward(100) —— 前行指定距离
color(“black”) —— 设置画笔颜色
pensize(10) —— 设置字体大小
write(“Hello”) —— 写字
circle(50) —— 绘制指定半径的圆环
done() —— 开启消息循环,使窗口保留,程序不自动退出
- 完整代码
#导入turtle
import turtle
# 设置画笔
turtle.showturtle() #(不用其实也没啥问题)
turtle.pensize(5)
# 蘸颜料,提起画笔,移动至指定位置,落笔,绘制蓝色圆环
turtle.color("blue")
turtle.penup()
turtle.goto(-110,0)
turtle.pendown()
turtle.circle(45)
# 蘸颜料,提起画笔,移动至指定位置,落笔,绘制黑色圆环
turtle.color("black")
turtle.penup()
turtle.goto(0,0)
turtle.pendown()
turtle.circle(45)
# 蘸颜料,提起画笔,移动至指定位置,落笔,绘制红色圆环
turtle.color("red")
turtle.penup()
turtle.goto(110,0)
turtle.pendown()
turtle.circle(45)
# 蘸颜料,提起画笔,移动至指定位置,落笔,绘制黄色圆环
turtle.color("yellow")
turtle.penup()
turtle.goto(-55,-45)
turtle.pendown()
turtle.circle(45)
# 蘸颜料,提起画笔,移动至指定位置,落笔,绘制绿色圆环
turtle.color("green")
turtle.penup()
turtle.goto(55,-45)
turtle.pendown()
turtle.circle(45)
# 蘸颜料,提起画笔,移动至指定位置,落笔,书写口号
turtle.color("black")
turtle.penup()
turtle.goto(-110,-80)
turtle.pendown()
turtle.write("同一个世界,同一个梦想",font=("华文行楷", 15, "italic"))
#程序本该结束,但保持窗口的消息循环,使程序保持运行,直到用户手动终止
turtle.done()
执行结果:
第六节:异常处理
几个常见的异常类型
异常处理,是为了程序的健壮性,防止程序发行运行时错误。
常见的异常类型有:
Syntax Error
——语法错误ZeroDivisionError
——零分母异常TypeError
——类型错误IndexError
——字符下标越界KeyError
——键错误ValueError
——值错误,没有找到子串EOFError
——文件末尾错误
异常的简单处理
在一段代码中,如果预知到可能存在发生异常的可能性,就要使用
try…except…
结构进行捕获和处理;
try一段业务代码,当执行到某一行发生异常时,系统会跳转至except…所统领的异常处理代码段中,正常的业务逻辑代码会终止于异常发生的那一行;
如果明知会发生异常而不去捕获,系统会在异常发生的地方崩溃;
例:
try:
# 主体逻辑
radius = eval(input("请输入圆的半径:"))
print("以%f为半径的圆面积是%.2f" % (radius, 3.14 * radius ** 2))
# 捕获了运行时异常
except:
# 异常处理逻辑
print("请重新输入")
执行结果:
分别处理不同种类的异常
上面的例子演示的是如何粗糙捕获和处理所有异常;
如果想对不同种类的异常分别进行不同的处理,则我们需要使用如下格式:
try:
<主业务逻辑>
except 异常1:
<处理方式1>
except 异常2:
<处理方式2>
...
except:
<其它异常的处理>
例如:
try:
mlist = [1, 2, 3]
print(mlist[4])
# 分类处理异常
except IndexError:
print("您造了一个IndexError")
except KeyError:
print("您造了一个KeyError")
except TypeError:
print("您造了一个TypeError")
# 捕获并处理其它异常
except:
print("您造了一个未知异常")
使用else
和finally
else
所辖的是没有发生异常时所执行的代码段,它是可选的;finally
所辖的是无论是否发生异常都一定会执行的代码段,它也是可选的;
例如:
#有try则至少有一个except
try:
mlist = [1, 2, 3]
print(mlist[2])
# 分类处理异常
except IndexError:
print("您造了一个IndexError")
except KeyError:
print("您造了一个KeyError")
else:
print("没有出现异常")
#无论是否发生异常都会执行的代码
finally: print("我不想执行")
执行结果:
为异常起一个别名
我们在捕获到某种异常时,可以给它起一个别名;
这个别名所代表的是异常抛出方所创造的异常实例;
拥有这个异常的实例后,我们就可以进而访问这个实例中的诸多属性和方法,来更精细化地对这一异常进行处理了;
例如:
try:
# 主体逻辑
radius = eval("001")
# 捕获某种异常,起一个别名e,e中包含了异常的报错信息
except Exception as e:
# 异常处理逻辑
print("出错了", e)
执行结果:
抛出异常
我们之所以能够捕获到一个异常的实例,是因为我们所调用的函数在其内部创建并抛出了一个异常实例;
这个实例被调用者捕获并处理;
下面的例子是一个计算圆面积的函数,当用户输入的半径为负数时,该函数会raise
一个Exception的实例,提示调用者半径是非法的;
这样调用者在因输入非法半径而崩溃后,就能够定位到出错的原因,进而进行处理了;
例:
def getArea():
radius = eval(input("请输入圆的半径:"))
if radius < 0:
raise Exception("非法的半径")#抛出异常,并打印信息
else:
print("这个半径正确,程序正常结束")
#调用者捕获和处理getArea()函数抛出的异常
try:
getArea()
# 捕获到异常
except Exception as e:
print(e)
执行结果:
自定义异常
系统所提供的诸多异常类,并不足以精确地覆盖各种具体业务场景,这时我们就需要用到自定义异常;
1、自定义的异常类,必须继承于系统的某个异常类,并在此基础上扩展;
2、常用来作为父类的异常类有Exception
和RuntimeException
;
3、一个没有继承系统异常类的普通类,是无法被抛出和处理的;
在自定义的异常类中,我们可以按业务逻辑的需要,自定义许多我们自己的属性和方法,这些都有助于调用者精确地进行异常定位和处理;
- 定义一个自定义的异常类
# 定义一个异常类:非法参数异常(继承于Exception)
class InvalidArgumentError(Exception):
def __init__(self, msg):
self.msg = msg
#定义一个返出去的发生异常的相关信息
def info(self):
return "两边之和必须大于第三边,两边之差必须小于第三边"
- 抛出自定义的异常信息
下面的例子定义的是一个非法三角形边长的异常的实例,当用户输入的三个整数无法构成一个三角形进而求取三角形面积时,我们抛出一个刚才定义好的异常来提示调用者做好预案处理工作;
import math
# 工具方法:计算以a,b,c为边长的三角形的面积
def getTriangleArea(a,b,c):
# 判断边长参数是否合法
if not ((a+b)>c and (b+c)>a and (a+c)>b):
# 如果用户输入的参数不合法,则抛出自定义好的异常和提示信息
# 创建一个InvalidArgumentError类的对象
raise InvalidArgumentError("边长参数不合法")
#如果合法,则进行计算
p = (a+b+c)/2
area = math.sqrt(p*(p-a)*(p-b)*(p-c))
print(area)
- 捕获并处理异常
调用者使用try…except结构包裹起可能抛出非法边长异常的代码;
在非法边长果然发生时,就能够调用异常实例所提供的属性和方法,来精确地提示用户错误的原因了;
if __name__ == '__main__':
try:
getTriangleArea(3, 4, 9)
# 捕获和处理异常
# e是工具方法所创建和抛出的异常对象
except Exception as e:
print(e)
print(e.msg)
print(e.info())
执行结果: