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))