生成器

"""
可迭代对象
任何可以使用for循环遍历的对象都是可迭代对象
    python中内置可迭代对象包括
    字符串 str
    列表   list
    元组   tuple
    集合   set
    字典   dict
​
迭代器
是用来实现可迭代对象内部遍历的机制,用于对可迭代对象更优雅高效的遍历
语法
    使用iter()把可迭代对象包裹后,可迭代对象就成了一个迭代器对象,使用__next__()可以一个一个访问里面的元素
    对象.__iter__  打印出来为迭代器本身
"""
# 列表正常遍历
list1 = [1,2,3,4,5]
for i in list1:
    print(i)
​
# 将列表(可迭代对象)转变为迭代器对象
iter1 = iter(list1)
print(type(iter1))
print(iter1.__next__())
print(iter1.__next__())
print(iter1.__next__())
num_4 = next(iter1)  # 使用变量接收里面的值
print(num_4)
print(type(num_4))
​
print('===============================================')
"""
生成器
用于快速生成多个数据,并且需要动态生成每个返回值(节省内存)
生成器的本质就是一个迭代器
同时可以使用__iter__和__next__方法
如果里面的元素已被遍历完则会显示报错
"""
# 生成器表达式
iter2 = (i for i in range(1, 6))  # 快速生成1-5的生成器对象
print(iter2)   # 打印为 生成器对象与内存中的地址
print(iter2.__iter__())  # 打印返回生成器本身
print(iter2.__next__())  # 使用__next__依次遍历里面的值
print(iter2.__next__())
print(iter2.__next__())
print(iter2.__next__())
print(iter2.__next__())
# print(iter2.__next__())  # 如果里面的元素已遍历完,则会报错
​
# 生成器函数 关键字yield与函数中return返回值用法相似
# 区别为yield输出一次值后就会暂停函数执行,直至下次next方法使用,以此类推
def func():
    yield 1
    yield 2
    yield 3
    yield 4
​
iter3 = func()
# 两种方式一样
print(iter3.__next__())
print(next(iter3))
​
print('=================================================')
# 无限自增函数生成
def test1():
    a = 0
    while True:
        a += 1
        yield a
test1 = test1()
print(test1.__next__())
print(test1.__next__())
print(test1.__next__())
print('==============================')
​
# 经典实例
# 斐波那契数列
# 输出的每一个数字都是前两个数字的和
def fibonacci(end):
    n, a, b = 0, 0, 1
    while n < end:
        a, b = b, a+b
        yield b
        n += 1
​
res = fibonacci(10)
print(res.__next__())
print(res.__next__())
print(res.__next__())
print(res.__next__())
print(next(res))
print(next(res))

装饰器

"""
装饰器:
    在不破坏目标函数原有的代码和功能的前提下,为目标函数增加新功能
用法:
    创建一个闭包函数,在闭包函数内调用目标函数
    将装饰函数作为参数,使用 @装饰函数 放在需要增加功能的函数上面
"""
​
# 装饰器的一般写法
def outer(func):
    def inner():
        print('我睡觉了')
        func()
        print('我起床了')
    return inner
@outer
def sleep():
    import random
    import time
    print('睡眠中......')
    time.sleep(random.randint(1, 5))
# fn = outer(sleep)
# fn()
sleep()
​
# 带参数装饰器
def compute(func):
    def data(*args,**kwargs):  # 使用不定长参数代替原函数中的参数
        import time
        print('正在计算中......')
        time.sleep(2)
        func(*args, **kwargs)
        print('计算完成')
    return data
​
@compute
def plus(a, b):
    print(a + b)
plus(1,10)
​
# 带返回值的装饰器
def compute1(func):
    def data1(*args,**kwargs):  # 使用不定长参数代替原函数中的参数
        import time
        print('正在计算中......')
        time.sleep(2)
        return func(*args, **kwargs) # 同样这里也要加上retrun返回值
    return data1
​
@compute1
def plus(a, b):
    return a + b
print('计算结果为:', plus(1, 10))
"""
内置装饰器
property
classmethod
staticmethod
"""
class person:
    name = '小明'  # 成员变量
    def __init__(self,name,gender):
        self.name = name
        self.gender = gender
    @property  # 将方法变为只读,不再需要传参,直接使用访问属性的方法进行访问
    def eat(self):
        return f'{self.name}准备吃饭'
​
    @classmethod  # 将此方法变成类方法,默认参数从self变成cls,无需实例化就可访问内置的成员变量和该方法
    def sleep(cls):
        print(f'{cls.name}准备睡觉')
    @staticmethod
    def play():  # 不再自动传入参数
        print('打豆豆')
​
zs = person('张三','男')
print(zs.eat)
​
person.sleep()  # @classmethod  直接使用类名调用方法
​
zs.play()

异常

"""
异常
用于处理报错信息的方法,可以自定义报错信息
"""
​
iter1 = (i for i in range(1,4))
try:
    print(next(iter1))
    print(next(iter1))
    print(next(iter1))
    print(next(iter1))
except:
    print('生成器已经结束')
​
​
try:
    with open('D:\softData\PycharmProjects\ChengQuEdu\\textfile.txt','r')as f:
        print(f.read())
except Exception as e:  # 可以使用Exception调出报错信息进行输出
    print(e)
    print('你所查询的文件不存在')
else:
    print('已查询到这个文件的所有内容')
finally:  # 以上的代码运行完成后,运行finally的内容
    print('查询完成')
​
​
"""
断言
assert
用于布尔类型判断,如果是True则
"""
a = 5
b = 10
assert a < b
​
# raise 手动抛出异常,可以自己修改报错后的提示内容
def division(x,y):
    if y == 0:
        raise ZeroDivisionError('除数不能为零')
    else:
        return x / y
division(10,0)

错误查找

ppt内容