柯里化
- 指的是将原来接受两个参数的函数变成新的接受一个参数的函数的过程。新的函数返回一个以原有第二个参数为参数的函数
- z = f(x, y) 转换成 z = f(x)(y)的形式
举个栗子
将加法函数柯里化:
def add(x, y):
return x + y
>>> def add(x):
>>> def _add(y):
>>> return x + y
>>> return _add
>>> add(4)(5)
9
**通过嵌套函数就可以把函数转换成柯里化函数
装饰器
在我理解看来,装饰器就是增强一个函数的附加功能,而不改变该函数的所以实现
比如说:我们想对 一个加法函数,做一个增强,就是额外打印输出一些信息
>>> def add(x,y):
>>> return x + y
实现1:
>>> def logger(fn):
>>> print('begin')
>>> x = fn(4,5)
>>> print('end')
>>> return x
>>> print(logger(add))
begin
end
9
这个函数看似增强的一些打印信息,但是没法传入参数,就有问题了,不通用
实现2:解决传参问题
>>> def logger(fn,*args,**kwargs):
>>> print('begin')
>>> x = fn(*args,**kwargs)
>>> print('end')
>>> return x
>>> print(logger(add,5,60))
begin
end
65
实现3:将这个函数柯里化
>>> def logger(fn):
>>> def _logger(*args,**kwargs):
>>> print('begin')
>>> ret = fn(*args,**kwargs)
>>> print('end')
>>> return ret
>>> return _logger
>>> add = logger(add)
>>> print(add(x=5, y=10))
begin
end
15
实现4: 使用装饰器语法糖
>>> def logger(fn):
>>> def _logger(*args,**kwargs):
>>> print('begin')
>>> ret = fn(*args,**kwargs)
>>> print('end')
>>> return ret
>>> return _logger
>>> @logger #等价于 add = logger(add)
>>> def add(x,y):
>>> return x + y
>>> print(40,50)
begin
end
90
functools模块
@functools.wraps(wrapped, assigned=WRAPPER_ASSIGNMENTS, updated=WRAPPER_UPDATES)
import functools,datetime,time
def logger(duration, func = lambda name, duration: print('{} took {}s'.format(name, duration))):
def _logger(fn):
@functools.wraps(fn)
def wrapper(*args,**kwargs):
start = datetime.datetime.now()
ret = fn(*args,**kwargs)
delta = (datetime.datetime.now() - start).total_seconds()
if delta > duration:
func(fn.__name__, duration)
return ret
return wrapper
return _logger
@logger(5) # add = logger(5)(add)
def add(x,y):
'this is a add function'
time.sleep(1)
return x + y
print(add(5, 6), add.__name__, add.__wrapped__, add.__dict__,add.__doc__, sep='\n')
输出:
11
add
<function add at 0x1033fca60>
{'__wrapped__': <function add at 0x1033fca60>}
this is a add function