来源商业新知网,原标题:干货 | Python进阶系列之学习笔记(四)
本篇为Python进阶干货系列第四篇,主要为大家详细介绍了Python条件判断、循环语句、循环控制、迭代器和生成器以及异常
目录
如果某些条件满足,才能做某件事情;条件不满足时,则不能做,这就是所谓的判断。
不仅生活中有,在软件开发中"判断"功能也经常会用到
(1)if 语句发
介绍
if 翻译成中文是 如果 的意思。if 后面写判断的条件。使用格式如下
使用格式
if 要判断的条件: 条件成立时,要做的事情
如果 if 判断的条件是正确的,那么就执行 if 下面缩进段内的代码。否则不执行
# 举个栗子
age = 30# 代表年龄30岁print("------if判断开始------")ifage >= 18:# 判断条件print("我已经成年了")# 条件成立则执行print("------if判断结束------")
实际操作:
执行过程:
(2)比较运算符:
刚刚在和大家讲解 if 的使用方式时,不知道观察仔细的各位有没有发现 if 后面的条件判断的写法,除了这个大于号,还有什么写法呢?
实际操作:
a = 3
b = 3print(a == b)# 检查两个值print(a != b)# != ,a 是否不等于 bprint(a > b)# > ,a 是否大于 bprint(a < b)# < ,a 是否小于 bprint(a >= b)# >= ,a 是否大于等于 bprint(a <= b)# <= ,a 是否小于等于 b
(3)逻辑运算符:
刚才上个知识点和大家讲的是比较的运算符,那么咱们再来看看逻辑运算符
实际操作:
a = 10
b =20c =30d =10print(a < banda > b)# and 当两侧的表达式都正确的时候,返回True,否则返回 False。print(a < borb > a)# or 当两侧的表达式,只要有一个是正确时就返回True。print(notb > a)# b > a 结果是正确的。但是 not 会返回 False。# 如果结果是错误的,则返回 True。
(4)if-else 语句
想一想:在使用 if 的时候,它只能做到满足条件时要做的事情。那万一需要在不满足条件的时候,做某些事,该怎么办呢? 答:使用 if-else
其使用格式如下:
if 条件:
满足条件时要做的事情1
满足条件时要做的事情2
满足条件时要做的事情3
...(省略)...
else:
不满足条件时要做的事情1
不满足条件时要做的事情2
不满足条件时要做的事情3
...(省略)...
# 举个栗子
chePiao = 1# 用1代表有车票,0代表没有车票ifchePiao == 1:# 判断条件print("还好买到车票了")print("终于可以回家陪伴父母了,珍惜~~~")else:# 条件不成立则执行 elseprint("没有车票,不能上车")print("我要再想想其它的办法")
实际操作:
执行过程:
(5)if-eilf-else 语句
if 能完成当条件成立时做的事情
if-else 能完成当条件成立时做事情 1 ,否则做事情 2
如果有这样一种情况:当 条件一 满足时做事情 1 ;当 条件一 不满足、条件二 满足时做事情2;当 条件二 不满足、条件三 满足时做事情3,那该怎么实现呢?
答:使用 eilf
其使用格式如下:
if 条件一成立:
执行事情1
elif 条件二成立:
执行事情2
elif 条件三:
执行事情3
# 举个栗子
score =77# 代表分数ifscore>=90andscore<=100:print('本次考试,等级为A')elifscore>=80andscore<90:print('本次考试,等级为B')elifscore>=70andscore<80:print('本次考试,等级为C')elifscore>=60andscore<70:print('本次考试,等级为D')elifscore>=0andscore<60:print('本次考试,等级为E')
实际操作:
执行过程:
二、Python 循环语 句
在Python中 for 循环可以遍历任何序列的项目,如一个列表或者一个字符串等。
(1)for 循环
for 循环,重点在于循环。可以理解为在某种情况下反复的做一些事情。比如咱们生活中的电子表,分别有时针分针和秒针,秒针从 0 开始,每一秒则递增1,60秒时,分钟递增1,就这样一直反复,这就可以理解为循环。
其使用格式如下:
for 临时变量 in 列表或者字符串等可迭代对象:
循环满足条件时执行的代码
# 举个栗子
name ='天下第一帅'forxinname:print(x)
实际操作:
执行过程:
(2)while 循环
Python 编程中 while 语句也是循环语句种的一种,主要用于循环执行程序,即在某条件下,循环执行某段程序,以处理需要重复处理的相同任务。
其使用格式为:
while 判断条件:
执行语句……
# 举个栗子
count=1# 表示为次数while(count<9):print('count 运行次数:',count)count=count+1print("while 循环条件不满足 count 等于 9,退出 while 循环")
实际操作:
(3)while 死循环
有一种循环叫死循环,一经触发,就运行个天荒地老、海枯石烂。
这是为什么捏?
因为 while 后面的条件一直成立。什么情况下会一直成立呢?
# 举个栗子
count=0whileTrue: # 判断条件一直为真,那么就会一直进行循环print("count:",count)count+=1#count=count+1
实际操作:
(1)break 结束循环
break 翻译成中文有:打破、折断、弄坏等意思。在 Python 中 break 的作用是 退出相关的所有的循环,结束所有循环。
# 举个栗子
count=0whileTrue:print('正在执行第'+str(count)+'循环')count+=1ifcount==10:print('检测到 count 等于 10 将执行 break 退出循环')breakprint('退出循环成功')
实际操作:
大家只需要记住 break 的作用是结束循环 ,就可以啦。
(2)continue 退出当前循环
Continue 退出是当前的循环,进入下一次循环.表示跳过当前这次循环,进行下一次循环
# 举个栗子
count=0whilecount<15:count+=1ifcount==10:print('检测到 count 等于 10 将执行 continue 跳过当前循环')continueprint('正在执行第'+str(count)+'循环')
实际操作:
continue 的作用是,跳出当前这一次循环。
在了解 Python 的数据结构时,容器(container)、可迭代对象(iterable)、迭代器(iterator)、生成器(generator)、列表/集合/字典推导式(list,set,dict comprehension)众多概念参杂在一起,难免让初学者一头雾水
容器比较容易理解,因为你就可以把它看作是一个盒子、一栋房子、一个柜子,里面可以塞任何东西。从技术角度来说,当它可以用来询问某个元素是否包含在其中时,那么这个对象就可以认为是一个容器,比如 list,set,tuple 都是容器对象
(1)可迭代对象
可以被 for 循环的语句统称为可迭代对象 如: list , set , dict , tuple,str
# 举个栗子
list1 = [1,2,3,4]dict1 = {"a":1,"b":2,"c":3}tuple1 = (1,2,3,4)foriinlist1print(i)
实际操作:
(2)不可迭代对象
无法使用 for 循环进行迭代的数据,称为不可迭代对象.
# 举个栗子
age = 17foriinage:print(i)
实际操作:
(3)迭代器
定义
迭代器内含 iter() 方法 和 next() 方法 . 对于 字符串,列表,字典,元组 等这类容器对象,在使用 for 循环时,会对这些容器调用 iter() 方法 , iter() 方法是 python 内置的函数,iter()函数会返回一个定义了 next() 方法的迭代器对象 .它在容器中逐渐访问容器内的元素 , next() 也是python 的内置函数,在 没有后续函数时 , next() 函数会抛出一个 StopIteration 异常
使用
# 举个栗子
name='我最帅,不接受反驳'name= iter(name)
实际操作:
(4)生成器
定义
生成器是创建迭代器的一个工具,写起来就像一个正常的函数一样,只是 在需要有返回数据的时候使用 yield 语句 ,每次 next() 方法被调用时,生成器会返回它脱离的位置(返回它脱离的位置和所有的数据值) 也就是说, 使用了 yield 关键字的函数不再是函数,而是生成器。
创建生成器的方法1
# 举个栗子
#a = [item*2foriteminrange(5)] 这个是列表推导式#a = (item*2foriteminrange(5)) 这个是生成器#不同的地方在于 列表推导式使用中括号,生成器使用圆括号.
实际操作:
创建 列表 a 和 生成器a 的区别仅在于最外层的 [ ] 和 ( ) ,列表a 是⼀个列表,⽽ 生成器a,是⼀个⽣成器。我们可以直接打印出列表a的每⼀个元素,⽽对于⽣成器a,我们可以按照迭代器的使⽤⽅法来使⽤,即可以通过next()函数、for循环、list()等⽅法使⽤。
创建生成器方法2
generator⾮常强⼤。如果推算的算法⽐较复杂,⽤类似列表⽣成式的 for 循环⽆法实现的时候,还可以⽤函数来实现。
我们仍然⽤上⼀节提到的斐波那契数列来举例,回想我们在上⼀节⽤迭代器的实现⽅式:
def fibonacci(n):
# 定义斐波那契数列的前2个值a =0b =1# 定义当前的位置current_index =0print("------------1111-----------")whilecurrent_index < n:# 定义要返回的值result = a# ⽣成新的 a、b值a,b =b,a+b# 让当前值+1current_index +=1print("-----------2222----------")yieldresultprint("-----------3333------------")# ⽣成器,⽣成斐波那契数列fib = fibonacci(5)value = next(fib)print(value)value = next(fib)print(value)
操作结果:
使⽤了yield关键字的函数不再是函数,⽽是⽣成器。(使⽤了yield的函数就是⽣成器)
yield关键字有两点作⽤: 1.保存当前运⾏状态(断点),然后暂停执⾏,即将⽣成器(函数)挂起 2.将yield关键字后⾯表达式的值作为返回值返回,此时可以理解为起到了return的作⽤
特点
生成器可以做到迭代器能做的所有事情,而且因为自动创建了 iter() 和 next() 方法,生成器会显得比较简洁一些,而且生成器相对更高效.使用生成器表达式取代列表解析可以同时节省内存.除了创建和保存程序状态的自动方法,当生成器终止时,还会自动抛出 StopIteration 异常。
(1)异常介绍
在介绍异常之前,咱们先看个例子:
# 举个小栗子
print(name)# 很简单的输出 name 变量数据
实际操作:
说明:
当我们在打印输出一个未被定义的变量时,Python 解释器就会为我们抛出一个 NameError 类型的错误,错误信息的描述是 : name 'name' is not defined 显示 名字 'name ' 没有被定义
异常
还有很多类型的异常错误,当程序抛出异常错误之后,程序就无法继续向下执行了.反而出现了一些错误的提示,这就是所谓的"异常"
(2)捕获异常
那么咱们有什么方法,可以将这个异常进行捕获吗?
可以使用 try ... except ...
try ... except ...捕获异常:
看个栗子:
# 先举个栗子
try:
print('-----test--1---')print(name)print('-----test--2---')exceptNameError:print('使用 try...except...成功捕获到异常')
实际操作:
说明:
此程序看不到任何错误提示(没有标红),因为用 except 捕获到了 NameError 异常 ,并添加了处理的方法(except 缩进段内的语句就是处理方法)
小总结
except ...捕获多个异常:
看个栗子:
try:
print('-----test--1---')open('123.txt','r')# 以 r 只读方式,打开文件 123.txtprint('-----test--2---')exceptNameError:print('使用 try ... except ... 捕获到 NameError 类型错误')
实际操作:
原因:
except 捕获的错误类型是 NameError ,而此时程序产生的异常为 FileNotFoundError ,所以 except 没有生效.
修改代码:
try:
print('-----test--1---')open('123.txt','r')# 以 r 只读方式,打开文件 123.txtprint('-----test--2---')exceptFileNotFoundError:print('使用 try ... except ... 捕获到 FileNotFoundError 类型错误')
这样 except 就可以成功捕获到 FileNotFoundError 类型的错误信息了. 那么其实, 实际开发过程中,捕获多个异常的方式如下:
try:
print('-----test--1---')open('123.txt','r')# 如果123.txt文件不存在,那么会产生 IOError 异常print('-----test--2---')print(num)# 如果num变量没有定义,那么会产生 NameError 异常except(IOError,NameError):#如果想通过一次except捕获到多个异常可以用一个元组的方式print('捕获到 IOError 或者 NameError 错误')
实际操作:
注意:
当 捕获多个异常时 ,可以把要 捕获的异常的名字 ,放到 except 后 ,并 使用元组的方式进行存储
获取异常的信息描述
来通过图片的方式,为大家进行详解
捕获所有异常
有些情况下,我们开发人员也不知道程序的运行会出现什么类型的错误,总不能每个类型错误都写一次吧?
当然不会了,Python 在捕获异常时,可以针对性写异常错误类型,也可以不写.
try:
print(name)except:print('捕获到程序出现异常')# 结果:捕获到程序出现异常
except 后面什么都不写的情况下,可以捕获全部异常类型的错误.但是眼尖的同学能发现,虽然捕获异常了,但是却没有了异常的信息描述.那么怎么办呢?
try:
print(name)except Exceptionasresult:print('捕获到程序出现异常:',result)
实际操作:
这次 except 后面写的是 Exception ,但是我没有写 NameError ,程序却成功捕捉到了异常。 因为 Exception 是常规错误的基类.所以一些常规的错误可以进行捕获 .
else 无异常则执行
咱们应该对 else 并不陌生,在 if 中,它的作用是当条件不满足时执行的实行;同样在try...except...中也是如此,即如果没有捕获到异常,那么就执行 else 中的事情
try:
num =100print(num)except NameErroraserrorMsg:print('产生错误了:%s'%errorMsg)else:print('没有捕获到异常,真高兴')
实际操作:
try ... finally ...
try...finally... 语句用来表达这样的情况:
在程序中,如果一个段代码必须要执行,即无论异常是否产生都要执行,那么此时就需要使用 finally。 比如文件关闭,释放锁,把数据库连接返还给连接池等.
无论有没有异常,最后都会执行 finally 下面的语句
# 举个栗子
try:num =100print(num)exceptNameErroraserrorMsg:print('产生错误了:%s'%errorMsg)else:print('没有捕获到异常,真开心')finally:# 可以和 else 一起使用.print('哎,对,就是开心~')
实际操作:
(3)异常的传递
异常的传递 函数嵌套,怎么理解呢,咱们向下看.
函数嵌套
如果一个函数发生异常,没有进行捕获,那么异常会传递给调用的函数.
# 举个例子
deffunc1():print("---正在执行 func1 ---开始")print(num)print("---正在执行 func1 ---结束")deffunc2():try:print("---正在执行 func2 ---开始")func1()print("---正在执行 func2 ---结束")except:print("---func2 捕捉到异常---")print("---无论func1 是否有异常,都执行这行代码---")func2()
大家猜猜,这两个函数的执行流程是什么?
实际操作:
这就是在函数嵌套中,如果出现异常,异常会逐层向上传递,异常出现后,异常下面的代码不会执行,直到 except 捕获异常为止.
(4)抛出自定义异常
你可以用 raise 语句 来 引发 一个 异常 。异常/错误对象必须有一个名字(自定义的类名),且它们应是Error 或 Exception 类的子类 。 下面是一个引发异常的例子:
class ShortInputException(Exception):
'''自定义的异常类'''def__init__(self, length, atleast):#super().__init__()self.length = lengthself.atleast = atleastdefmain():try:s = input('请输入 --> ')# 根据输入的字符串的长度进行判断iflen(s) <3:# raise引发一个你定义的异常raiseShortInputException(len(s),3)exceptShortInputExceptionasresult:#x这个变量被绑定到了错误的实例print('ShortInputException: 输入的长度是 %d,长度至少应是 %d'% (result.length, result.atleast))else:print('没有异常发生.')main()
运行结果:
注意:
以上程序中,关于代码 #super().__init__() 的说明。 这一行代码,可以调用也可以不调用,建议调用,因为 __init__ 方法往往是用来对创建完的对象进行初始化工作,如果在子类中重写了父类的 __init__ 方法,即意味着父类中的很多初始化工作没有做,这样就不保证程序的稳定了,所以在以后的开发中, 如果重写了父类的__init__ 方法,最好是先调用父类的这个方法,然后再添加自己的功能
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。