闭包
count = 0
def arith(op, a, b):
def add():
print count, ':', a, '+', b, '=', a + b
def sub():
print count, ':', a, '-', b, '=', a - b
def mul():
print count, ':', a, '*', b, '=', a * b
def div():
print count, ':', a, '/', b, '=', a / b
if(op == '+'):
return add
elif(op == '-'):
return sub
elif(op == '*'):
return mul
elif(op == '/'):
return div
count = 1; a = 18; b = 8
add1 = arith('+', a, b)
count = 2; a = 28; b = 18
add2 = arith('+', a, b)
print add1
print add2
add1()
add2()
output:
<function add at 0x10aedd0c8>
<function add at 0x10aedd2a8>
2 : 18 + 8 = 26
2 : 28 + 18 = 46
解释:
- 嵌套函数add中,count,a,b指向各自对象,调用时才获取值
- add在调用add1和add2时调用,此时获取count,a,b指向对象值
count = 0
def arith(op, a, b):
def initCount(count):
def add():
print count, ':', a, '+', b, '=', a + b
def sub():
print count, ':', a, '-', b, '=', a - b
def mul():
print count, ':', a, '*', b, '=', a * b
def div():
print count, ':', a, '/', b, '=', a / b
if(op == '+'):
return add
elif(op == '-'):
return sub
elif(op == '*'):
return mul
elif(op == '/'):
return div
return initCount(count)
count = 1; a = 18; b = 8
add1 = arith('+', a, b)
count = 2; a = 28; b = 18
add2 = arith('+', a, b)
print add1
print add2
add1()
add2()
output:
<function add at 0x10fcf8758>
<function add at 0x10fd00c80>
1 : 18 + 8 = 26
2 : 28 + 18 = 46
解释:
- 嵌套函数add中,count,a,b指向各自对象,调用时才获取值
- initCount在调用arith时调用,此时获取counts指向对象值
- add在调用add1和add2时调用,此时获取a,b指向对象值
总结:
- 闭包,closure,是包含数据的行为,闭包是嵌套函数的一种应用,以外围函数返回值形式返回的嵌套函数就是闭包
- 闭包本质是嵌套函数,因此闭包可引用外围函数变量(包括参数),但闭包(嵌套函数)只是保存变量(引用),并非保存变量(引用)指向对象指,只有当闭包(嵌套函数)被调用时才获取变量(引用)指向对象值
装饰
def log(func):
def wrapper(*args, **kw):
print 'start call %s():' %func.__name__
return func(*args, **kw)
return wrapper
@log
def add(a, b):
print a, '+', b, '=', a + b
add(18, 8)
output:
start call add():
18 + 8 = 26
解释:
- decorator @log等同于add = log(add)
def log(text):
def decorator(func):
def wrapper(*args, **kw):
print 'start %s %s():' %(text, func.__name__)
return func(*args, **kw)
return wrapper
return decorator
@log('exec')
def add(a, b):
print a, '+', b, '=', a + b
add(18, 8)
output:
start exec add():
18 + 8 = 26
解释:
- decorator @log等同于add = log('exec')(add)
总结: