一、
闭函数:封闭的意思,函数被封闭起来
包函数:函数内部包含对外层函数作用域名字的引用
实例:
def f1():
x=10
def f2():
print(x)
return f2
场景:主要就是原本的函数(f2)不能够再去给他增加新的形参的时候,而你这个函数内部恰好又需要有外部传参进来,这时候就可以用到闭包函数。
二、装饰器
定义一个函数(类或者其他的),这个函数的功能就是用来装饰其他函数的
也就是说这个函数是用来给其他函数添加额外功能的
开放封闭原则:
开放:对扩展功能(增加功能)开放,扩展功能的意思是在源代码不做任何改变的情况下,为其增加功能。
封闭:对修改源代码是封闭的
def inside(group,s,z):
print(group)
print(s)
print(z)
def recharge(num):
for i in range(num,100):
time.sleep(0.05)
print(i)
print('充满')
return 100
#下面的函数就是装饰器示例
"""
此时如果上面两个函数的参数发生了变化,并且已经修改的函数,但是如果调用的时候使用了
装饰器来调用,在函数修改后,调用函数的地方就可以不用修改了,
"""
def outer(func):
def wrapper(*args,**kwargs):
start = time.time()
respense = func(*args,**kwargs)
end = time.time()
print(end-start)
return respense
"""
通过下面的两行代码,能够将内存地址直接指向原函数,而不是wrapper函数,
并且函数注释也是指向了原函数。
"""
wrapper.__name__ = func.__name__
wrapper.__doc__ = func.__doc__
return wrapper
"""
语法糖
就是在定义函数的时候直接声明调用装饰器函数,就会将装饰后的函数地址后返回
并赋值给原来的函数变量
"""
@outer #此处就相当于funcc = outer(funcc)
def funcc(a,b,c)
pause
为了能够将内存地址直接指向原函数,而不是wrapper函数,并且函数注释也是指向了原函数除了使用上面直接赋值的方法,还可以导入一个装饰器在完成。
导入wraps
from functool import wraps
from functool import wraps
#下面的函数就是装饰器示例
"""
此时如果上面两个函数的参数发生了变化,并且已经修改的函数,但是如果调用的时候使用了
装饰器来调用,在函数修改后,调用函数的地方就可以不用修改了,
"""
def outer(func):
@wraps(func)
#有了上面这行代码,下面的wrapper.__name__,wrapper.__doc__赋值代码就可以去掉了。
def wrapper(*args,**kwargs):
start = time.time()
respense = func(*args,**kwargs)
end = time.time()
print(end-start)
return respense
"""
通过下面的两行代码,能够将内存地址直接指向原函数,而不是wrapper函数,
并且函数注释也是指向了原函数。
"""
wrapper.__name__ = func.__name__
wrapper.__doc__ = func.__doc__
return wrapper
三、有参装饰器
语法糖限制了装饰器只能有一个参数。
应用样例:
def auth(source):
def outer(func):
def wrapper(*args,**kwargs):
name = input("输入账号").strip()
pwd = input("输入密码").strip()
if source == 'file':
ptint('基于文件')
if name == 'jack' and pwd == '123':
res = func(*args,**kwargs)
return res
else:
print('错误')
elif source == 'sql':
print('基于sql')
else:
print('不支持')
return wrapper
return outer
@auth('file')
def home():
print('welcome')
@auth('sql')
def index():
pass
四、装饰器叠加使用
#装饰器的叠加使用
@outer3 #home = =outer3(home) #outer3.wrapper
@outer2 #home = =outer2(home) #outer2.wrapper
@outer1 #home = =outer1(home) #outer1.wrapper
def home():
pass
"""
装饰器的调用顺序是:outer1->outer2->outer3
"""
五、迭代器
可迭代对象:
只要内置有__iter__()方法的就可以称之为可迭代对象。可以转换为迭代器的对象
dict = {key1:'value1',key2:'value2',key3:'value3'}
res = dict.__iter__()
while True:
try:
print(res.__next__())
except StopIteration: #用来捕获异常
break
如果想再次取值,就必须重新调用一次:res = dict.__iter__(),否则就会直接抛出异常
迭代器对象:内置有__next__()方法,并且还内置有__iter__()方法的对象。
迭代器对象调用__next__()方法,就会得到迭代器的下一个值,迭代器对象调用__iter__()方法,得到的是迭代器本身。
六、生成器
生成器就是迭代器,
def func():
print('第一次执行')
yield 1
print(‘第二次执行’)
yield 2
print('第三次执行')
yeild 3
#上面函数虽然没有return,但是会返回一个生成器,可以使用__next_来取值。
yield表达式:
yield会将函数暂停到当前位置,并返回yield后面的值。
yield可以接收send()过来的值,并赋值给一个变量,比如:g.send(10)。