Python第十课(函数3) >>>转到思维导图>>>转到中二青年
闭包函数
1.定义在函数内部的函数
2.内部函数内部函数引用了外部函数名称空间作用域的名字
只要满足以上两点都叫做闭包函数
def func(): name = jason‘ # 先在内部找name没有再往上层找 有了就停止查找 def inner(): print(name) # 现在内部找name没有再往上层找 return inner f = func() # f获取到的是inner的内存地址 f() # 相当于执行 inner() # 函数在定义阶段名字的查找孙旭就已经固定死了,不会因为函数调用位置的变化而变化
给函数传参的两种方式
1.直接传参
def index(name): print(name)
2.闭包
def outter(name): # name = ‘jason‘ def index(): print(name) return index
装饰器
器:就是一个工具
装饰:就是给被装饰对象添加新的功能
开放封闭原则:
开放:对扩展开放
封闭:对修改封闭
装饰器(可调用对象)必须遵循的两个原则:
1.不改变被装饰对象的源代码
2.不改变被装饰对象(可调用对象)调用方法
可调用:callable
def new(): print(‘这是原始函数‘) def outter(func): def inner(): print(‘这是内部函数,这里可以加新功能‘) func() # 这里的func是你想调用的最原始的函数的内存地址,加上()直接调用 print(‘这是内部函数,这里可以加新功能‘) return inner # 这里不加括号 返回的是inner函数的内存地址 new = outter(new) # 括号内的new指向的是最原始的new函数的内存地址,前面的new获取的是outter函数的返回值,返回值我们自定义了返回 inner函数的内存地址 # 总结:前面的new获取的是inner的内存地址,后面括号内的new指向的就是最原始的new的内存地址 new()
扩展:import time
import time time.time() 获取时间戳(秒) 当前时间距离1970-1-1 00:00:00 所经过的秒数 time.sleep(seconds) 让程序暂定几秒钟
装饰器语法糖
把装饰器赋值给最近的可调用对象
将最近的可调用对象的名字当做参数自动传入装饰器外层函数
书写时两者之间不要空行,应紧紧挨着
# 先写装饰器 def outter(func): def inner(): print(‘这里可以加新功能‘) func() # 这里的func是你想调用的最原始的函数的内存地址,加上()直接调用 print(‘这里可以加新功能‘) return inner # 这里不加括号 返回的是inner函数的内存地址 @outter # new = outter(new) 把装饰器赋值给最近的可调用对象,并将对象名传入。 def new(): print(‘这是原始函数‘) new()
装饰器修复技术
1.返回原来的函数的函数名
2.返回原来的函数的注释
from functools import wraps def outter(func): @ wraps(func) # 装饰器修复加在最内层函数正上方 def inner(*args,**kwargs): # * **在形参中使用 # 执行被装饰函数之前你可以做的操作 res = func(*args,**kwargs) # * # 执行被装饰函数之后你可以做到操作 return res return inner @outter def index(username,*args,**kwargs): """index注释""" pass print(index)
无参装饰器
from functools import wraps def outter(func): @wraps(func) # 加在最内层函数正上方 def inner(*args,**kwargs): # *和**在形参中使用 print(‘这里可以加新功能‘) # 执行被装饰函数之前你可以做的操作 func(*args,**kwargs) # 这里的func是你想调用的最原始的函数的内存地址,加上()直接调用, *和**在实参中使用 print(‘这里可以加新功能‘) # 执行被装饰函数之后你可以做到操作 return inner # 这里不加括号 返回的是inner函数的内存地址 @outter # new = outter(new) 把装饰器赋值给最近的可调用对象,并将对象名传入。 def new(): print(‘这是原始函数‘) new()
有参装饰器
from functools import wraps choice = input(‘>>>:‘) def wrappers(data): def outter(func): @wraps(func) # 加在最内层函数正上方 def inner(*args,**kwargs): if data == ‘1‘: # 如果用户输入‘1’那么执行index() # 执行被装饰函数之前你可以做的操作 res = func(*args,**kwargs) # * **在实参中使用 res接收原始函数的返回值 # 执行被装饰函数之后你可以做到操作 return res return 999 return inner return outter @wrappers(choice) # index = wrappers(index) def index() print(‘123‘) return 666 # 原始函数的返回值 index()
多个装饰器
1. 装饰的时候 从下往上执行
2. 执行的时候 从上往下执行
def outter1(func1): #func1=wrapper2的内存地址 print(‘加载了outter1‘) def wrapper1(*args,**kwargs): print(‘执行了wrapper1‘) res1=func1(*args,**kwargs) return res1 return wrapper1 def outter2(func2): #func2=wrapper3的内存地址 print(‘加载了outter2‘) def wrapper2(*args,**kwargs): print(‘执行了wrapper2‘) res2=func2(*args,**kwargs) return res2 return wrapper2 def outter3(func3): # func3=最原始的那个index的内存地址 print(‘加载了outter3‘) def wrapper3(*args,**kwargs): print(‘执行了wrapper3‘) res3=func3(*args,**kwargs) return res3 return wrapper3 @outter1 # outter1(wrapper2的内存地址)======>index=wrapper1的内存地址 @outter2 # outter2(wrapper3的内存地址)======>wrapper2的内存地址 @outter3 # outter3(最原始的那个index的内存地址)===>wrapper3的内存地址 def index(): print(‘from index‘) print(‘======================================================‘) index() # 1. 加载顺序(outter函数的调用顺序):自下而上 # 2. 执行顺序(wrapper函数的执行顺序):自上而下
END
原文:https://www.cnblogs.com/renvip/p/11178817.html