Python基础语法(一)迭代器、生成器、异常处理

迭代器

可迭代对象

在Python中凡是可以通过“for i in 序列”遍历的都是可迭代对象,也可以通过isinstance(序列,Iterable)查看。

创建可迭代对象:
只要对象中含有_ _ ter _ _()方法,它就是一个可迭代对象:

示例:

from collections import Iterable

list1=[1,2,3,4]
tuple1=(1,2,3,4)
set1={1,2,3,4}
dict1={1:'a',2:'b',3:'c',4:'d'}
class test():#自定义可迭代对象类
    def __iter__(self):
        pass
t=test()
print("\nlist1是不是可迭代对象:",isinstance(list1,Iterable))#True
for l1 in list1:
    print(l1,end=" ")#1 2 3 4

print("\ntuple1是不是可迭代对象:",isinstance(tuple1,Iterable))#True
for t1 in tuple1:
    print(t1,end=" ")#1 2 3 4

print("\nset1是不是可迭代对象:",isinstance(set1,Iterable))#True
for s1 in set1:
    print(s1,end=" ")#1 2 3 4

print("\ndict1是不是可迭代对象:",isinstance(dict1,Iterable))#True
for d1 in dict1:
    print(d1,end=" ")#1 2 3 4
    
print("\nt是不是可迭代对象:",isinstance(t,Iterable))

迭代器对象

可迭代对象不等于迭代器,迭代器是一个可以记录遍历位置的对象,它不会像序列遍历一样,一下子将全部数据生成,而是根据需要来生成数据,这样会做可以大大节省内存资源,我们可以通过isinstance(对象,iterator)判断是否为迭代器。

创建迭代器对象:
包含有_ _iter _ _ ()和 _ _ next _ _()方法的对象是迭代器对象,_ _ _iter _ _ ()返回一个特殊的迭代器对象,这个对象自动调用 _ _ next _ _()方法返回一个值,最后抛出异常Stopiteration结束迭代。

示例:

from collections import Iterator, Iterable


class test():
    def __iter__(self):
        pass
    def __next__(self):
        pass
    
t=test()

print("\nt是不是可迭代对象:",isinstance(t,Iterable))#True
print("\nt是不是迭代器对象:",isinstance(t,Iterator))#True

完整的迭代器:
一个完整的迭代器不仅仅要包含方法,还要能实现功能;_ _ iter _ _ ()需要返回一个迭代器对象,而 _ _ next _ _()则需要记录数值,并返回数值

示例:

from collections import Iterator, Iterable


class test():
    def __init__(self,n):
        self.start=1
        self.end=1
        self.nlen=n

    def __iter__(self):
        return self#返回迭代器对象,自己是迭代器,所以可以返回自己
    
    def __next__(self):
        if self.end<=self.nlen:#迭代未完就进入返回值操作
            n1=self.start#记录数值
            self.start+=1#改变数值
            self.end+=1#改变个数
            return n1#抛出数值
        else:#迭代完成就抛出异常
            raise StopIteration

t=test(10)
print("t是不是可迭代对象:",isinstance(t,Iterable))#True
print("t是不是迭代器对象:",isinstance(t,Iterator))#True
print("单独获取:",next(t))#1
print("遍历获取:",end="")
for i in t :#因为1被取出了,所以从2开始取
    print(i,end=" ")#2 3 4 5 6 7 8 9

注意:
1、可迭代对象不一定是迭代器对象
2、迭代器对象一定是可迭代对象
3、list、tuple、set、str、dict是可迭代对象,但不是迭代器对象。

生成器

生成器和迭代器相类似,他们都不会一下子生成全部数据,而是根据需要生成,生成器里面存放的是生成数值的算法,它不会立即执行,而是你什么时候调用,就什么时候执行并返回数值,当你需要大量数据又不想占用太多内存时,就可以使用生成器。

创建生成器

1、()推导式创建:

g1=(i for i in range(10))#()推导式可创建一个生成器对象
print(next(g1))#获取第一个值:0
print(next(g1))#获取第二个值:1
print(next(g1))#获取第三个值:2
print(type(g1))#获取对象类型:<class 'generator'>

2、yield关键字创建:

def test(l):
    num=0
    while num<=l:#使用yield关键字最好配合上循环
        num+=1
        yield num#暂停函数,抛出num,下次调用next从这里的下一句执行,
        		#如果后面没有yield会报错,所以要配合循环

t=test(10)
print(type(t))#<class 'generator'>
print(next(t))#获取第一个值:1
print(next(t))#获取第一个值:2
print(next(t))#获取第一个值:3

3、yield关键字创建+传参:

import time


def test(l):
    num=0
    while num<=l:
        num+=1
        res=yield num
        print(res)
        
t=test(10)
print(type(t))#<class 'generator'>
print(t.send(None))#传递空值,开启生成器,抛出1,暂停函数
time.sleep(1)
print(t.send(10))#执行yield后面语句,打印res:10,抛出2,暂停函数
time.sleep(1)
print(t.send(20))#执行yield后面语句,打印res:20,抛出3,暂停函数

异常处理

异常是指在语法逻辑正确的情况下出现的问题,例如我们在做计算器时,除数不能为0,而用户又输入的0,这时候系统就会抛出异常,我们需要对异常进行捕捉和处理,异常除了可以由系统抛出外,还可以是人为抛出。

系统抛出异常

try-except语句(常见用法)

try后面的代码块放置的是可能出现异常的代码块,当出现异常后会被捕捉,执行except后面的异常处理代码块,没有异常的话不执行异常处理,except可以写多个

语法格式:

try:
	可能引发异常的代码块
except [,异常类型 as e]:
	捕捉到异常后的处理代码块

示例:

try:
    num=int(input())
    print(10/num)
except ZeroDivisionError as e:#异常分类处理,输入0的情况
    print("0不可以作为除数!")
except ValueError as e:#输入非数字的情况
    print("你输入的不是数字!")

注意:
异常只能被捕捉一次,当有多个except时,把异常类按范围从小到大排,因为当前面的大异常类把异常捕捉了,后面的后面就捕捉不到,这样不利于对异常情况的分类

try-except-else语句

try-except-else语句在前者的基础上加了else这个分支,else的作用和except相反,当没有异常时执行else后面的代码块,else分支可写可不写,没有强制要求。

语法格式:

try:
	可能产生异常的代码块
except 异常类 as e:
	捕获到异常后的处理代码块
else:
	没有异常时的代码块

示例:

try:
    num=int(input())
    print(10/num)
except ZeroDivisionError as e:
    print("0不可以作为除数!")
except ValueError as e:
    print("你输入的不是数字!")
else:#当没有异常时,输出结果后,输出“顺利计算完成”;有异常时不输出“顺利计算完成”
    print("顺利计算完成")

try-except-else-finally 语句

该语句是在上句的基础上引入了finally分支,这个finally的作用是无论有没有异常都会执行finally后面的代码块,finally也是可写可不写,非强制要求。

语法格式:

try:
	可能产生异常的代码块
except 异常类 as e:
	捕获到异常后的处理代码块
else:
	没有异常时的代码块
finally:
	有没有异常都要执行的代码块

示例:

try:
    num=int(input())
    print(10/num)
except ZeroDivisionError as e:
    print("0不可以作为除数!")
except ValueError as e:
    print("你输入的不是数字!")
else:
    print("顺利计算完成")
finally:#不管是否出现异常都会输出“本次计算过程全部完成”
    print("本次计算过程全部完成")

人为抛出异常

断言(assert)

断言用于判断,当某些条件不成立(False)时,抛出AssertionError

语法格式:

assert 表达式,错误信息

示例:

try:
    num=int(input())
    assert num>0,"输入的必须是正数!"#设置断言,当num>0不成立时,抛出AssertionError异常
    print(10/num)
except ZeroDivisionError as e:
    print("0不可以作为除数!")
except ValueError as e:
    print("你输入的不是数字!")
except AssertionError as e:#捕捉断言抛出的异常
    print(e)#打印错误信息
else:
    print("顺利计算完成")
finally:
    print("计算过程全部完成")

手动抛出异常(raise)

如果需要人为抛出异常就需要用到raise关键字,它和assert相类似,不过raise可以指定抛出异常的类型,raise经常配合自定义经常类使用

创建自定义异常类:

class myerror(Exception):#异常类必须继承自Exception
    def __init__(self,*args,**kwargs):
        if args:
            self.error=args
        if kwargs:
            self.error=kwargs
    def __str__(self):
        return str(*self.error)

语法格式:
raise 异常类(错误信息)

示例:

class myerror(Exception):
    def __init__(self,*args,**kwargs):
        if args:
            self.error=args
        if kwargs:
            self.error=kwargs
    def __str__(self):
        return str(*self.error)
try:
    num=int(input())
    assert num>0,"输入的必须是正数!"
    if num>99:#当num大于99时,触发自定义异常类,抛出异常
        raise myerror("数值范围过大!")#抛出的异常可以是自定义异常类也可以是系统异常类
    if num%10!=0:
        raise#只有raise时默认抛出RuntimeError
    print(10/num)
except myerror as e:#捕获异常
    print(e)#打印错误信息
except ZeroDivisionError as e:
    print("0不可以作为除数!")
except ValueError as e:
    print("你输入的不是数字!")
except AssertionError as e:
    print(e)
else:
    print("顺利计算完成")
finally:
    print("计算过程全部完成")

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值