python函数三 (装饰器)
一。函数名(学名:第一类对象)
函数名本质上就是函数的内存地址。通俗点就是特殊的普通变量
def func(): print(111) func() print(func) # 结果: # 111 # <function func at 0x00000150713F6048>
1.可以被引用(即可以赋值给其他变量)
def func(): print('in func') f = func f() # 结果: # in func
2.可以被当作容器类型的元素
def func(): print(111) def func2(): print(222) def func3(): print(333) li = [func(),func2(),func3()] for i in li: i # 结果: 111 222 333
3.可以当作函数的参数和返回值
def func(): print(111) func() def func2(): return func f = func2() f() # 结果: 从上到下运行,遇见func()后调用函数打印一个111, # 111 之后到f = func2(),调用func2()返回给f一个值func, # 111 最后f()即func()再次调用后打印一个111
第一类对象(first-class object)指
1.可在运行期创建
2.可用作函数参数或返回值
3.可存入变量的实体。
二。闭包
闭包的定义:内层函数,对外层函数(非全局)的变量的引用,叫做闭包
闭包的用处:如果说你内存函数是个闭包,python内部有一个机制,遇到闭包
他会在内存中开启一个内存空间,不会随着函数的结束而关闭
from urllib.request import urlopen print(urlopen('http://www.cnblogs.com/jin-xin/articles/8259929.html').read()) def index(url): content = urlopen(url).read() def get(): with open('爬虫','a') as f1: f1.write(content.decode('utf-8')) return get index('http://www.cnblogs.com/jin-xin/articles/8259929.html')()
判断是否是闭包函数:__closure__
ef func(): name = 'alex' def func2(): print(name) func2() print(func2.__closure__) #含有 cell 就是闭包 None 不是闭包 func() # 结果: # alex # (<cell at 0x0000011AD42A75B8: function object at 0x0000011AD6178A60>, <cell at 0x0000011AD42A75E8: str object at 0x0000011AD6177378>) name = 'alex' def func(): def func2(): print(name) func2() print(func2.__closure__) # None 不是闭包 func() # 结果: # alex # None def func(x): def func2(): print(x) func2() print(func2.__closure__) func('alex') # 结果: # alex # (<cell at 0x0000029D98CE75B8: str object at 0x0000029D98D77538>,)
三。在外层函数内部执行内部函数
def func(): def func2(): print(111) func2() func() def func(): def func2(): print(111) return func2 func()()
四。装饰器
比如计算一个函数的执行效率
1.最low的写法
import time def func(): print('我们都一样') start_time = time.time() time.sleep(0.1) func() end_time = time.time() print('------的执行效率%s'%(end_time-start_time)) # 结果: # 我们都一样 # ------的执行效率0.10034990310668945
2.进阶写法
import time def func(): print('我们都一样') def timmer(): start_time = time.time() time.sleep(0.1) func() end_time = time.time() print('------的执行效率%s'%(end_time-start_time)) timmer() # 虽然也可以运行,但是影响了func()的正常运行,还可以在进阶
3.简单的装饰器
import time def func(): print('我们都一样') def timmer(f): def inner(): start_time = time.time() time.sleep(0.1) f() end_time = time.time() print('------的执行效率%s'%(end_time-start_time)) return inner func = timmer(func) func() # 可以理解为func,timmer,inner通过赋值转换,加参数,最后只剩一个func, # 这样就可以运行程序,又可以知道执行效率
4.带返回值的装饰器(语法糖的用法)
@timmer 相当于 #func = timmer(func) 即待求的函数名 = 新函数名(待求的函数名)
import time def timmer(func): def inner(*args,**kwargs): start_time = time.time() time.sleep(0.1) ret = func(*args,**kwargs) end_time = time.time() print('------执行效率%s'%(end_time-start_time)) return ret return inner @timmer def func(): return '天若有情天亦老,人间正道是沧桑' # func() 打印返回值的话不能写这步,否则函数会在调用一次,多打印一次执行效率 print(func()) # 结果: # ------执行效率0.1002659797668457 # 天若有情天亦老,人间正道是沧桑
5.通用装饰器
def wrapper(func): def inner(*args,**kwargs): '''执行函数前的操作''' ret = func(*args,**kwargs) '''执行函数后的操作''' return ret return inner @wrapper def func(): print(111) func()