本文主要是介绍柯里化与无参装饰器,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
柯里化
柯里化的概念:柯里化(Currying)在Python中是一种编程技术,它将原本接受多个参数的函数转换为一系列接受单个参数的函数。这种方法以逻辑学家Haskell Curry的名字命名。
简而言之就是将一次函数调用变成先放入一个参数得到的中间函数对象,然后再对中间函数对象进行传参,这样可以将多参数函数变成多个单参数函数。
def add(x):def inner(y,z):return x+y+zreturn innerprint(add(1)(2,3))
在第一个例子中,我们先将x传入得到一个带有x参数的函数对象,然后再对这个函数对象继续传入y,z两个参数,柯里化的程度是取决于我们的需要的,我们当然也可以将其分成三个函数,如下图
def add(x):def innner(y):def inner_1(z):return x+y+zreturn inner_1return innnerprint(add(1)(2)(3))
现在,我们对柯里化有了一定了解,但我们该怎么把柯里化和装饰器关联在一起呢?
装饰器
你可以顾名思义,装饰器就是装饰函数用的,函数太单调?我们可以给它加一些功能让它尽可能丰满一些,为了丰富函数,有必要引入柯里化吗,我直接在函数里写不就行了?这就要考虑到代码侵入性问题了,我们将非业务代码(装饰代码)写在函数里,这就产生了业务与非业务代码的纠缠,这不利于后期代码的修改,何况,如果我想为多个函数进行装饰,难道我要一个一个copy过去?这显然不切实际,所以我们运用了函数的思想,把装饰代码封装到一个函数中,然后再将其应用在目标函数上,这实际上是将函数当作参数传入一个函数(高阶函数),而柯里化在其中的作用就是分割,它将装饰函数应用在目标函数然后返回一个装饰过的目标函数,但这个过程不会影响原目标函数,这可能有一些抽象,接下来我们应用实例来说明。
def add(x,y):return x+ydef logger(fn):def wrapper(*args,**kwargs):print("{} function is called. {},{}".format(fn.__name__,args,kwargs))ret = fn(*args,**kwargs)return retreturn wrapperadd = logger(add)
我们定义了一个日志修饰函数,这个修饰器的作用就是说明一下目标函数的使用情况,我们使用柯里化将参数分离,这样我们就能不用传入目标函数的参数了,比如说这个add (x,y),如果不使用柯里化,那我们就要传入x,y的值了,但这不是我们注重的部分,我们的目的是将修饰器应用在目标函数上,至于参数是什么,这不是我们考虑的范畴。所以柯里化其实就是把目标函数的参数与目标函数本身分割开,让我们可以更加关注修饰情况。
add = logger(add)
我们看到这行代码,其实柯里化的意图已经明显了,我们始终需要的就是这行代码,至于其他参数我们暂时不考虑,而这行代码在python中也作为语法糖(修饰器的语法)变换了存在形式。
在python中,我们用@来表示修饰函数。
装饰器语法
@标识符
标识符指向一个函数,用一个函数来装饰它下面的函数,logger称为装饰器函数,add称为被装饰或被包装函数
本质上来看,无参数装饰器logger实际上等效为一个参数的函数
无参数装饰器 logger
@logger 会把它下面紧挨着的函数的标识符提上来作为它的实参
如此,我们可以写成:
def logger(fn):def wrapper(*args,**kwargs):print("调用前增强功能")print("{} function is called. {},{}".format(fn.__name__,args,kwargs))ret = fn(*args,**kwargs)print("调用后增强功能")return retreturn wrapper@logger
def add(x,y):return x+y
print(add(1,2))
以上,就是无参装饰器的基本内容,下一篇我们将讨论有参装饰器的使用。
这篇关于柯里化与无参装饰器的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!