装饰器和迭代器
装饰器
一.装饰器简介
在不更改原功能函数内部代码,并且不改变调用方法的情况下为原代码扩展新的功能
二.闭包
一.什么是闭包?
闭包 = 函数 + 一个封闭的作用域
二.什么是封闭的作用域?
外部无法修改的作用域
封闭作用域----->闭包函数外层的作用域
三.闭包函数有什么特性
1、函数嵌套函数
2、外层函数return返回的是 内层函数
3、内层函数引用外部的非全局变量
四.例如
def a(func): @wraps(func) def aa(*args, **kwargs): print('前置') function = func(*args, **kwargs) function.age = 12 print('后置') return function.__dict__ return aa
三.函数装饰器的用法
1.装饰单个函数
def one(): print("我是one函数") def two(fun): print("开始运行befor") fun() print("结束运行after") two(one)
在使用装饰器前首先需要明白函数可以通过参数的形式去传递。上面代码中two函数就是一个简单的装饰器,
fun参数表示的是修饰的函数
2.修饰单个带参函数
def two(fun): def three(*args, **kwargs): print("开始运行befor") fun(*args, **kwargs) print("结束运行after") return three def one(name): print("我是log函数") one = two(one) one("李明")
two函数中返回的是three,在one=twp(one),也就相当于one为three函数来运行。这里简单介绍下*args,**kwargs作用。
*args:在运行函数传参时不确定传几个参数,可用*占位来代替未知数量参数
def one(*args, **kwargs):#args类型为元组 for i in args: print(i) one("李明", "王二", "张三")
**kwargs:当传入的是键值对格式的时候,可用kwargs
def one(*args, **kwargs):#kwargs为字典类型 for k, v in kwargs.items(): print("k", k, "v", v) one(name="李明", age=12, sex="男")
3.@键的使用
def two(fun): def three(*args, **kwargs): print("开始运行befor") fun(*args, **kwargs) print("结束运行after") return three @two def one(name): print("我是log函数") one("li")
我们可以看出,在被修饰的函数前加上@装饰器,可实现同样的效果,@two就相当于one=two(one)
4.带参的装饰器
def two_01(name): def two(fun): def three(*args, **kwargs): print("开始运行befor") fun(*args, **kwargs) print("结束运行after") return three return two @two_01("这里传入个参数即可") def one(): print("我是log函数") one()
二.类装饰器的用法
1.带参的函数
class one: def __init__(self, fun): self.fun = fun def __call__(self, *args, **kwargs): print("开始执行前置") self.fun() print("开始执行结尾") @one def two(): print("我是非常复杂的程序") two()
类装饰器中有两个函数init初始化,和call把类变成一个可调用的对象
2.带有参数的类装饰器
class one: def __init__(self, name): self.name = name def __call__(self, fun): def one_01(): print("开始执行前置") fun() print("开始执行结尾") return one_01 @one("李明") def two(): print("我是非常复杂的程序") two()
此时接收被装饰的函数就是call,
3.被装饰带参的类
def a(func): @wraps(func) def aa(*args, **kwargs): print('前置') function = func(*args, **kwargs) function.age = 12 print('后置') return function.__dict__ return aa @a class ClaB: def __init__(self, name): self.name = name b = ClaB('里面') print(b)
1.可以再装饰器中定义被装饰器的属性字段
funcuion.age=12
2.@wraps()作用:将被装饰的函数的特殊属性保存到装饰器函数上,如:('__module__', '__name__', '__qualname__', '__doc__','__annotations__')
若没有wraps,那么在aa中打印print(aa.__name__)为aa,而不是被装饰的函数昵称
迭代器
迭代器有两个重要的方法iter和next,下面看下具体的用法
str = "1234" str = iter(str) #定义一个迭代器 print(next(str))#next为迭代下一个 print(next(str)) print(next(str))
其实除了iter()和next()外,for循环也可遍历
str = "1234" for i in str: print(i)
如何判断一个对象是否可迭代呢::isinstance()方法
from collections import Iterable str = "1234" print(isinstance(str,Iterable))
isinstance()里有两个参数,可判断两种参数类型是否相等,相等的话返回True,否则返回false

浙公网安备 33010602011771号