返回函数
返回闭包时牢记一点:返回函数不要引用任何循环变量,或者后续会发生变化的变量。
要引用循环变量时,方法是再创建一个函数,用该函数的参数绑定循环变量当前的值,无论该循环变量后续如何更改,已绑定到函数参数的值不变。
利用闭包返回一个计数器函数,每次调用它返回递增整数:
def createCounter():
num = 0
def counter():
nonlocal num
num += 1
return num
return counter
if __name__ == '__main__':
counterA = createCounter ()
print ( counterA () , counterA () , counterA () , counterA () , counterA () ) # 1 2 3 4 5
counterB = createCounter ()
if [counterB () , counterB () , counterB () , counterB ()] == [1 , 2 , 3 , 4]:
print ( '测试通过!' )
else:
print ( '测试失败!' )
匿名函数
在Python中,对匿名函数提供了有限支持。匿名函数lambda只能有一个表达式,不用写return,返回值就是该表达式的结果。
请用匿名函数改造下面的代码:
def is_odd(n):
return n % 2 == 1
L = list(filter(is_odd, range(1, 20)))
L = list(filter(lambda n : n % 2 == 1, range(1, 20)))
print(L)
装饰器
我们要增强函数的功能,但又不希望修改now()函数的定义,这种在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator)。
函数对象有一个_name_属性,可以拿到函数的名字:
now.name
‘now‘
请设计一个decorator,它可作用于任何函数上,并打印该函数的执行时间:
参考程序
import time, functools
def metric(fn):
@functools.wraps(fn)
def wapper(*args,**kw):
start = time.time()
x = fn(*args,**kw)
print ( '%s execute in %s ms' % (fn.__name__ , (time.time () - start) * 1000) )
return x
return wapper;
@metric
def fast(x, y):
time.sleep(0.0012)
return x + y;
@metric
def slow(x, y, z):
time.sleep(0.1234)
return x * y * z;
if __name__ == '__main__':
f = fast(11, 22)
s = slow(11, 22, 33)
if f != 33:
print('测试失败!')
elif s != 7986:
print('测试失败!')
偏函数
偏函数(Partial function)可以通过设定参数的默认值,可以降低函数调用的难度。
functools.partial可以帮助我们创建一个偏函数,可以直接使用下面的代码创建一个新的函数int2,使调用int2时进行二进制转换:
import functools
int2 = functools.partial(int, base=2)
int2(‘1000000’)
64
functools.partial的作用就是,把一个函数的某些参数给固定住(也就是设置默认值),返回一个新的函数,调用这个新函数会更简单。
import functools
def int_(i):
int2 = functools.partial(int, base=2)
num = int2(i)
print(num)
def max_(j):
max2 = functools.partial(max,j)
mun = max2(1,3,8,7,9)
print(mun)
if __name__ == '__main__':
a1 = input('please input a number:')
int_(a1)
a2 = int(input ( 'please input a number:' ))
max_(a2)