def pri(): return sum #函数执行后返回了另外一个函数对象sum print(type(pri()))
D:\>py -3 a.py
def func1(func): return func([1,2,3]) func1(sum) ''' func1(sum) #--->6 #sum->sum([1,2,3]) #pri-->pri([1,2,3])--->不符合函数定义,会报错 '''
执行结果:
def func(): x =100 def func1(): print(x) return func1 func()()---等价于 a=func() a()
-----》》》分析过程: >>> def func(): ... x =100 ... def func1(): ... print(x) ... return func1 ... >>> func() #加一个括号是调用了func这个函数,执行完后返回的是func1的函数对象;如果想调用func1()打印x的话就得再加一个(),即func()() <function func.<locals>.func1 at 0x00000150A43FA620> >>> func()() 100
x =100 def func1(): print(x) return None return func1
def a(): time1=time.time() i =1 while i<100000000: i+=1 time2=time.time() print("time elapsed:%s" %(time2-time1)) def b(): time1=time.time() i =1 while i<990000000: i+=1 time2=time.time() print("time elapsed:%s" %(time2-time1))
def timer(func): time1=time.time() func() #做了一次函数调用 time2=time.time() print("time elapsed:%s" %(time2-time1)) def a(): i =1 while i<100000000: i+=1 def b(): i =1 while i<990000000: i+=1 timer(a) timer(b)
import time def timer(func): def func1(): time1=time.time() func() #做一次函数调用 time2=time.time() print("time elapsed:%s" %(time2-time1)) return func1 #闭包:func+func1 @timer def a(): i =1 while i<100000000: i+=1 a() a #a等价于timer(a),由python编译器自动完成的。 a() #a()等价于timer(a)()
import time def timer(func): #装饰函数 def wrapper(): time1=time.time()#定义函数调用前干的事儿 print("******") func() #做一次函数调用 time2=time.time()#定义函数调用后干的事儿 print("******-----------") print("time elapsed:%s" %(time2-time1)) return wrapper #闭包:func(闭包变量)+wrapper(闭包函数) @timer def a(): i =1 while i<100000000: i+=1 print("a is over!") def b(): i =1 while i<100000000: i+=1 #a #a等价于timer(a),由python编译器自动完成的。 a() #a()等价于timer(a)() b()
import time def timer(func): #装饰函数 def wrapper(arg): time1=time.time()#定义函数调用前干的事儿 print("******") func(arg) #做一次函数调用 time2=time.time()#定义函数调用后干的事儿 print("******-----------") print("time elapsed:%s" %(time2-time1)) return wrapper #闭包:func(闭包变量)+wrapper(函数) @timer def a(count): print("执行次数:",count) i =1 while i<count: i+=1 print("a is over!") a(20)
import time def timer(func): #装饰函数 def wrapper(*arg,**kw): time1=time.time()#定义函数调用前干的事儿 print("******") func(*arg,**kw) #做一次函数调用 time2=time.time()#定义函数调用后干的事儿 print("******-----------") print("time elapsed:%s" %(time2-time1)) return wrapper #闭包:func(闭包变量)+wrapper(函数) @timer def a(count): print("执行次数:",count) i =1 while i<count: i+=1 print("a is over!") @timer def b(count1,count2,count3): print("执行次数:",count1+count2+count3) a(100) b(200,300,count3=1000)
装饰器九步法:
# -*- coding:utf-8 -*-
'''示例1: 最简单的函数,表示调用了两次'''
def myfunc():
print ("myfunc() called.")
myfunc()
myfunc()
E:\>py -3 a.py
myfunc() called.
myfunc() called.
第二步:使用装饰函数在函数执行前和执行后分别附加额外功能
'''示例2: 替换函数(装饰)装饰函数的参数是被装饰的函数对象,返回原函数对象 装饰的实质语句: myfunc = deco(myfunc)''' def deco(func): print ("before myfunc() called.") func() print (" after myfunc() called.") return func def myfunc(): print (" myfunc() called.") myfunc = deco(myfunc) myfunc() myfunc()
E:\>py -3 a.py
before myfunc() called.
myfunc() called.
after myfunc() called.
myfunc() called.
myfunc() called.
第三步:
'''示例3: 使用语法@来装饰函数,相当于“myfunc = deco(myfunc)” 但发现新函数只在第一次被调用,且原函数多调用了一次''' def deco(func): print ("before myfunc() called.") func() print (" after myfunc() called.") return func @deco #等价于:deco(myfunc) def myfunc(): print (" myfunc() called.") myfunc() myfunc()
E:\>py -3 a.py
before myfunc() called.
myfunc() called.
after myfunc() called.
myfunc() called.
myfunc() called.
------->>>>>>
第四步:使用内嵌包装函数来确保每次新函数都被调用
'''示例4: 使用内嵌包装函数来确保每次新函数都被调用, 内嵌包装函数的形参和返回值与原函数相同,装饰函数返回内嵌包装 函数对象''' def deco(func): def _deco(): print ("before myfunc() called.") func() print (" after myfunc() called.") # 不需要返回func,实际上应返回原函数的返回值 return _deco @deco def myfunc(): print (" myfunc() called.") return 'ok' myfunc() #---->执行闭包函数_deco() myfunc() #---->执行闭包函数_deco()
#myfunc=deco(myfunc)----->返回一个闭包:_deco的函数+myfunc
E:\>py -3 a.py
before myfunc() called.
myfunc() called.
after myfunc() called.
before myfunc() called.
myfunc() called.
after myfunc() called.
def deco(func): def _deco(): print ("before myfunc() called.") func() print (" after myfunc() called.") # 不需要返回func,实际上应返回原函数的返回值 return _deco 闭包:_deco+func @deco def myfunc(): print (" myfunc() called.") return 'ok' myfunc=deco(myfunc) myfunc是什么?是闭包:_deco+myfunc myfunc()--->_deco() myfunc()--->_deco() def outer(name): def inner(): print(name) return inner 闭包:inner+name
第五步:对带参数的函数进行装饰
'''示例5: 对带参数的函数进行装饰, 内嵌包装函数的形参和返回值与原函数相同,装饰函数返回内嵌包装 函数对象''' def deco(func): def _deco(a, b): print ("before myfunc() called.") ret = func(a, b) print (" after myfunc() called. result: %s" % ret) return ret return _deco @deco def myfunc(a, b): print (" myfunc(%s,%s) called." % (a, b)) return a + b myfunc(1, 2) myfunc(3, 4)
E:\>py -3 a.py
before myfunc() called.
myfunc(1,2) called.
after myfunc() called. result: 3
before myfunc() called.
myfunc(3,4) called.
after myfunc() called. result: 7
第六步:对参数数量不确定的函数进行装饰
'''示例6: 对参数数量不确定的函数进行装饰, 参数用(*args, **kwargs),自动适应变参和命名参数''' def deco(func): def _deco(*args, **kwargs): print ("before %s called." % func.__name__) ret = func(*args, **kwargs) print (" after %s called. result: %s" % (func.__name__, ret)) return ret return _deco @deco def myfunc(a, b): print (" myfunc(%s,%s) called." % (a, b)) return a+b @deco def myfunc2(a, b, c): print (" myfunc2(%s,%s,%s) called." % (a, b, c)) return a+b+c myfunc(1, 2) myfunc(3, 4) myfunc2(1, 2, 3) myfunc2(3, 4, 5)
E:\>py -3 a.py
before myfunc called.
myfunc(1,2) called.
after myfunc called. result: 3
before myfunc called.
myfunc(3,4) called.
after myfunc called. result: 7
before myfunc2 called.
myfunc2(1,2,3) called.
after myfunc2 called. result: 6
before myfunc2 called.
myfunc2(3,4,5) called.
after myfunc2 called. result: 12
第七步:被装饰函数加参数:带参数的装饰器本质都是两层闭包
'''示例7: 在示例4的基础上,让装饰器带参数, 和上一示例相比在外层多了一层包装。 装饰函数名实际上应更有意义些''' def deco(arg): def _deco(func): def __deco(): print ("before %s called [%s]." % (func.__name__, arg)) func() print (" after %s called [%s]." % (func.__name__, arg)) return __deco return _deco @deco("mymodule") def myfunc(): print (" myfunc() called.") @deco("module2") def myfunc2(): print (" myfunc2() called.") myfunc() myfunc2()
'''
1)多了一步:deco("hello") ---》返回了闭包:__deco+s
deco=闭包:__deco+s
2)@deco--->__deco(func)+s--->返回了一个闭包_deco+func+s
后面的过程跟上一步的过程一样。
'''
E:\>py -3 a.py
before myfunc called [mymodule].
myfunc() called.
after myfunc called [mymodule].
before myfunc2 called [module2].
myfunc2() called.
after myfunc2 called [module2].
第八步:让装饰器带 类 参数
'''示例8: 装饰器带类参数''' class locker: def __init__(self): print ("locker.__init__() should be notcalled.") @staticmethod def acquire(): print ("locker.acquire() called.(这是静态方法)") @staticmethod def release(): print (" locker.release() called.(不需要对象实例)") def deco(cls): '''cls 必须实现acquire和release静态方法''' def _deco(func): def __deco(): print("before %s called [%s]." %(func.__name__, cls)) cls.acquire() try: return func() finally: cls.release() return __deco return _deco @deco(locker) def myfunc(): print (" myfunc() called.") myfunc() myfunc()
E:\>py -3 a.py
before myfunc called [<class '__main__.locker'>].
locker.acquire() called.(这是静态方法)
myfunc() called.
locker.release() called.(不需要对象实例)
before myfunc called [<class '__main__.locker'>].
locker.acquire() called.(这是静态方法)
myfunc() called.
locker.release() called.(不需要对象实例)
第九步:装饰器带类参数,并分拆公共类到其他py文件中,同时演示了对一个函数应用多个装饰器
'''mylocker.py: 公共类 for 示例9.py''' class mylocker: def __init__(self): print("mylocker.__init__() called.") @staticmethod def acquire(): print("mylocker.acquire() called.") @staticmethod def unlock(): print(" mylocker.unlock() called.") class lockerex(mylocker): @staticmethod def acquire(): print("lockerex.acquire() called.") @staticmethod def unlock(): print(" lockerex.unlock() called.") def lockhelper(cls): '''cls 必须实现acquire和release静态方法''' def _deco(func): def __deco(*args, **kwargs): print("before %s called." %func.__name__) cls.acquire() try: return func(*args, **kwargs) finally: cls.unlock() return __deco return _deco
'''示例9: 装饰器带类参数,并分拆公共 类到其他py文件中 同时演示了对一个函数应用多个装饰 器''' from mylocker import * class example: @lockhelper(mylocker) def myfunc(self): print (" myfunc() called.") @lockhelper(mylocker) @lockhelper(lockerex) def myfunc2(self, a, b): print (" myfunc2() called.") return a + b if __name__=="__main__": a = example() a.myfunc() print(a.myfunc()) print (a.myfunc2(1, 2)) print (a.myfunc2(3, 4))