一、迭代器
什么式迭代?
迭代是访问容器元素的一种方式。迭代器是一个可以记住遍历的位置的对象。
迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。
什么式可迭代对象?
可迭代对象:可以直接作用于for循环的对象(如何判断是否可以迭代?)
一类是集合数据类型,如list, tuple,dict, set,str等;
一类是generator,包括生成器和带yield的generator function。
什么式迭代器?
1.可以被next()函数调用并不断返回下一个值的对象称为迭代器:Iterator。
2.生成器都是Iterator对象,但list、dict、str虽然是Iterable,却不是Iterator。
3.把list、dict、str等Iterable变成Iterator可以使用iter()函数
迭代器与生成器的区别
1)迭代器是一个更抽象的概念,任何对象,如果它的类有next方法和iter方法返回自己本身。对于string、list、dict、tuple等这类容器对象,使用for循环遍历是很方便的。
在后台for语句对容器对象调用iter()函数,iter()是python的内置函数。iter()会返回一个定义了next()方法的迭代器对象,它在容器中逐个访问容器内元素,next()也是python的
内置函数。在没有后续元素时,next()会抛出一个StopIteration异常
2)生成器(Generator)是创建迭代器的简单而强大的工具。它们写起来就像是正规的函数
,只是在需要返回数据的时候使用yield语句。每次next()被调用时,生成器会返回它脱离>的位置(它记忆语句最后一次执行的位置和所有的数据值)
区别:生成器能做到迭代器能做的所有事,而且因为自动创建了iter()和next()方法,生成器
显得特别简洁,而且生成器也是高效的,使用生成器表达式取代列表解析可以同时节省内存。除了创建和保存程序状态的自动方法,当发生器终结时,还会自动抛出StopIteration异常
二、闭包与装饰器
闭包
什么是闭包?
闭包的概念就是当我们在函数内定义一个函数时,这个内部函数使用了外部函数的临时 变量,且外部函数的返回值是内部函数的引用时,我们称之为闭包。
闭包再理解? 内部函数对外部函数作用域里变量的引用(非全局变量),则称内部函数为闭包。
nonlocal关键字? 显式的指定变量不是闭包的局部变量
闭包的一个常用场景就是装饰器
def line_conf(a, b):
def line(x):
return a * x + b
return line #返回值为内部函数的函数名
装饰器Decorator
写代码要遵循 开放封闭 原则,虽然在这个原则是用的面向对象开发,但是也适用于函数式编程,简单来说,它规定已经实现的功能代码不允许被修改,但可以被扩展,即:
1、封闭:已实现的功能代码块
2、开放:对扩展开发
装饰器的应用场景
- 引入日志
- 函数执行时间统计
- 执行函数前预备处理
- 执行函数后清理功能
- 权限校验等场景
- 缓存
装饰器的组成:
< 函数+实参高阶函数+返回值高阶函数+嵌套函数+语法糖 = 装饰器 >
语法糖
装饰符@类型于回调函数,只需在开头加上@+装饰器函数名就可以,把其它的函数作为自己的入参,在目的函数执行前,执行自己的操作然后返回目的函数
通用装饰器模版
因为在项目中,我们需要用装饰器去装饰很多个函数,所以用*args和**kwargs变量来传递参数
"""
def decorator(fun):
def wrapper(*args, **kwargs): # args, kwargs是形参
# 在函数之前做的操作
res = fun(*args, **kwargs) # *args, **kwargs是实参, *args, **kwargs是在解包
# 在函数之后添加操作
return res
return wrapper
@装饰器的名字
@decorator ======> add=decorator(add)
def add():
pass
add()
"""
带参数的装饰器
如果装饰器需要传递参数, 在原有的装饰器外面嵌套一个函数即可
"""
装饰器的框架
"""
def auth(type):
def wrapper1(fun):
def wrapper(*args, **kwargs):
if type=='local':
user = input("User:")
passwd = input("Passwd:")
if user == 'root' and passwd == 'westos':
result = fun(*args, **kwargs)
return result
else:
print("用户名/密码错误")
else:
print("暂不支持远程用户登录")
return wrapper
return wrapper1
"""
# python中装饰器的语法糖结构: @funName ===>
# python中装饰器结构如果为@funName() ====> 默认跟的不是函数名, 先执行改函数, 获取函数返回结果 ====》 @funNameNew
@函数名 add=函数名(add)
@函数名() @新的函数名
"""
@auth(type='remote')
def home():
print("这是主页")
home()
函数可被多个装饰器装饰
1). 上面装饰器先执行, 下面的装饰器后执行;
2). 函数先被哪个装饰器装饰呢? 函数先被下面的装饰器装饰;
def is_login(fun):
def wrapper1(*args, **kwargs):
print("判断是否登录......")
result = fun(*args, **kwargs)
return result
return wrapper1
def is_permission(fun):
def wrapper2(*args, **kwargs):
print("判断是否有权限......")
result = fun(*args, **kwargs)
return result
return wrapper2
@is_login # delete = is_login(delete)
@is_permission
def delete():
return "正在删除学生信息"
result = delete()
print(result)
在这个程序里面我们需要清楚多个装饰器执行的之后是怎么样的一个过程
"""
**** 被装饰的过程:
1). delete = is_permission(delete) # delete = wrapper2
2). delete = is_login(delete) # delete = is_login(wrapper2) # delete = wrapper1
*******被调用的过程:
delete() ------> wrapper1() ---> wrapper2() ---> delete()
"""