def outer(part1):
def inner(part2):
return part2*part1
return inner
f = outer(33)
f(100)
3300
f(11)
363
在这个例子中实现了一个功能: f(x) =33*x
,其中 f(x)
代表了内层函数的功能体,
x代表内层函数的参数,也就是说 outer
函数返回了一个函数,而这个函数的参数(33)来自外层函数,
可以把外层函数的参数理解成配置,于是通过配置的不同,便得到了不同的运算结果,这就叫闭包。
闭包的实现得益于__call__
方法,而装饰器就是闭包,也就是说如果要理解装饰器,一定要重视__call__
这个内建方法。
import time
装饰器函数
def readFile(func):
def _deco(path):
start_time = time.time()
f = open(func(path),'r')
end_time = time.time()
print("readFile costs %ss." % (end_time - start_time))
return f.read()
return _deco
配置函数
@readFile
def location(path):
return path
print(location('test.txt'))
readFile costs 0.0002422332763671875s.
这是一种比较简单的装饰器,其实调用是 @readFile = readFile(location)
。
下面再看装饰器带参数的例子,这也是 flask
里用得最多的。
class locker:
def __init__(self):
print("locker.__init__() should be not called.")
@staticmethod
def acquire():
print("locker.acquire() called.(这是静态方法)")
def deco(cls):
def _deco(func):
def __deco():
print("before %s called [%s]." % (func.__name__, cls))
cls.acquire()
return func()
return __deco
return _deco
@deco(locker)
def myfunc():
print(" myfunc() called.")
myfunc()
before myfunc called [<class '__main__.locker'>]. locker.acquire() called.(这是静态方法) myfunc() called.
装饰器写起来比理解起来容易。只有自己着手去写,才能真正理解装饰器。