閉包
- 閉包函數必須有內嵌函數
- 內嵌函數需要引用該嵌套函數的上一級變量
- 閉包函數必須返回內嵌函數
案例
def line_conf(a, b):
def line(x):
return a * x + b
return line
# 只需要變換參數a,b,就可以獲得不同的直線表達函數
line1 = line_conf(1, 1)
line2 = line_conf(4, 5)
print(line1(5), line2(5))
裝飾器
裝飾器本質上是一個函數,該函數用來處理其他函數,它可以讓其他函數在不需要修改代碼的前提下增加額外的功能,裝飾器的返回值也是一個函數對象
簡單裝飾器
def show_time(func):
def wrapper():
start_time = time.time()
func()
end_time = time.time()
print('spend %s' % (end_time - start_time))
return wrapper
@show_time # foo=show_time(foo)
def foo():
print('foo')
time.sleep(3)
@show_time # bar=show_time(bar)
def bar():
print('bar')
time.sleep(2)
foo()
# foo
# spend 3.000171422958374
bar()
# bar
# spend 2.001114845275879
帶參數的裝飾器
def time_logger(flag=0):
def show_time(func):
def wrapper(*args, **kwargs):
start_time = time.time()
result = func(*args, **kwargs)
end_time = time.time()
print('spend %s' % (end_time - start_time))
if flag:
print('記錄時間到日誌')
return result
return wrapper
return show_time
@time_logger(3) # show_time=time_logger(3); add=show_time(add)
def add(*args, **kwargs):
time.sleep(1)
return sum(args)
@time_logger(0)
def fac(n):
return reduce(lambda x, y: x * y, range(1, n + 1))
print(add(2, 7, 5))
# spend 1.0000569820404053
# 記錄時間到日誌
# 14
print(fac(10))
# spend 0.0
# 3628800