python——高阶函数——闭包 装饰

时间:2021-09-25 19:04:33

闭包

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)
总结:
  • 装饰,decorator,从语法上简化了闭包应用