#最简单的无参闭包函数
deffunc1()
name='ares'
deffunc2()print(name)#有参和返回值的闭包函数
deftimmer(func):def wrapper(*args,**kwargs):
start_time=time.time()
res=func(*args,**kwargs)
stop_time=time.time()print('run time is %s' %(stop_time-start_time))returnresreturn wrapper
二、高阶函数
1)函数接收的参数是一个函数名
2)函数的返回值是一个函数名
3)满足上述条件任意一个,都可称之为高阶函数
#高阶函数应用1:把函数当做参数传给高阶函数
importtimedeffoo():print('from the foo')deftimmer(func):
start_time=time.time()
func()
stop_time=time.time()print('函数%s 运行时间是%s' %(func,stop_time-start_time))
timmer(foo)#总结:我们确实为函数foo增加了foo运行时间的功能,但是foo原来的执行方式是foo(),现在我们需要调用高阶函数timmer(foo),改变了函数的调用方式#高阶函数应用2:把函数名当做参数传给高阶函数,高阶函数直接返回函数名
importtimedeffoo():print('from the foo')deftimmer(func):
start_time=time.time()returnfunc
stop_time=time.time()print('函数%s 运行时间是%s' %(func,stop_time-start_time))
foo=timmer(foo)
foo()#总结:我们确实没有改变foo的调用方式,但是我们也没有为foo增加任何新功能
高阶函数总结
1.函数接收的参数是一个函数名
作用:在不修改函数源代码的前提下,为函数添加新功能,
不足:会改变函数的调用方式
2.函数的返回值是一个函数名
作用:不修改函数的调用方式
不足:不能添加新功能
三、函数嵌套
#函数的嵌套定义
deff1():deff2():deff3():print('from f3')print('from f2')
f3()print('from f1')
f2()#print(f1)
f1()'''from f1
from f2
from f3'''
四、装饰器
1、定义:
器即函数
装饰即修饰,意指为其他函数添加新功能
装饰器定义:本质就是函数,功能是为其他函数添加新功能
2、装饰器遵循的原则:开放封闭原则(对扩展是开放的,对源码修改是封闭的)
即、1)不修改被装饰函数的源代码
2)为被装饰函数添加新功能后,不修改被装饰函数的调用方式
3、装饰器,装饰器本质可以是任意可调用对象,被装饰的对象也可以是任意可调用对象,
装饰器的功能是:在不修改被装饰对象源代码以及调用方式的前提下为期添加新功能
装饰器=高阶函数+函数嵌套+闭包
基本框架
#这就是一个实现一个装饰器最基本的架子
deftimer(func):defwrapper():
func()return wrapper
例:
defdeco(fn):defwapper():
fn()returnwapper
@decodeffoo():print('what are you 弄啥嘞')
foo()
统计一个函数运行时间的装饰器
import time
import random
#装饰器
def timmer(func):
# func=index
def wrapper():
start_time = time.time()
func() #index()
stop_time=time.time()
print('run time is %s' %(stop_time-start_time))
return wrapper
#被装饰函数
def index():
time.sleep(random.randrange(1,5))
print('welecome to index page')
def home():
time.sleep(random.randrange(1,3))
print('welecome to HOME page')
index=timmer(index) #index=wrapper
home=timmer(home)
index() #wrapper()
home()
装饰器的语法:在被装饰对象的正上方的单独一行,@装饰器名字,#@timer就等同于index=timmer(index)
importtimeimportrandom#装饰器
deftimmer(func):defwrapper():
start_time=time.time()
func()
stop_time=time.time()print('run time is %s' %(stop_time-start_time))returnwrapper#被装饰函数
@timmer #index=timmer(index)
defindex():
time.sleep(random.randrange(1,5))print('welecome to index page')#@timmer #home=timmer(home)#def home():#time.sleep(random.randrange(1,3))#print('welecome to HOME page')
index() #wrapper()#home()
加多个装饰器:
#加多个装饰器
importtimeimportrandom#装饰器
deftimmer(func):defwrapper():
start_time=time.time()
func()
stop_time=time.time()print('run time is %s' %(stop_time-start_time))returnwrapperdefauth(func):defdeco():
name=input('name:')
password=input('password:')if name == 'egon' and password == '123':print('login successful')
func()#wrapper()
else:print('login err')returndeco#被装饰函数 #多个装饰函数,从上往下添加,调用时从下往上
@auth #index=auth(wrapper) #index=deco #index=auth(wrapper) #index=deco
@timmer #index=timmer(index) #index=wrapper
defindex():#time.sleep(random.randrange(1,5))
time.sleep(3)print('welecome to index page')defhome():
time.sleep(random.randrange(1,3))print('welecome to HOME page')#index() #deco()#home()
装饰器修订:
#装饰器修订
importtimeimportrandom#装饰器
deftimmer(func):def wrapper(*args,**kwargs):
start_time=time.time()
res=func(*args,**kwargs) #接收参数
stop_time=time.time()print('run time is %s' %(stop_time-start_time))return res #增加返回值
returnwrapper#被装饰函数
@timmerdefindex():
time.sleep(random.randrange(1,5))print('welecome to index page')
@timmerdefhome(name):
time.sleep(random.randrange(1,3))print('welecome to %s HOME page' %name)return 123123123123123123123123123123123123123123index()
res1=index()print('index return %s' %res1)
res2=home('egon') #wraper()
print('home return %s' %res2)
扩展:
"""python内置装饰器
在python中有三个内置的装饰器,都是跟class相关的:staticmethod、classmethod、property.
@staticmethod 是类的静态方法,其跟成员方法的区别是没有self参数,并且可以在类不进行实例化的情况下调用
@classmethod 与成员方法的区别在于所接收的第一个参数不是self(类实例的指针),而是cls(当前类的具体类型)
@property 是属性的意思,表示可以通过类实例直接访问的信息"""
classFoo(object):def __init__(self,var):
super(Foo,self).__init__()
self._var=var
@propertydefvar(self):returnself._var
@var.setterdefvar(self,var):
self._var=var
f=Foo('var1')print(f.var)
f.var='var2'
print(f.var)"""注意,对于Python新式类(new-style class),如果将上面的 “@var.setter” 装饰器所装饰的成员函数去掉,
则Foo.var 属性为只读属性,使用 “foo.var = ‘var 2′” 进行赋值时会抛出异常。
但是,对于Python classic class,所声明的属性不是 read-only的,所以即使去掉”@var.setter”装饰器也不会报错。"""