当前位置: 首页 > news >正文

柯里化与无参装饰器

柯里化

柯里化的概念:柯里化(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))

以上,就是无参装饰器的基本内容,下一篇我们将讨论有参装饰器的使用。

 

 

http://www.lryc.cn/news/344561.html

相关文章:

  • Spring事务失效的场景
  • Python基础学习之datetime模块
  • 在AI大模型中全精度和半精度参数是什么意思?
  • 刷题记录2
  • 【配置】Docker搭建JSON在线解析网站
  • 2024.5.2 —— LeetCode 高频题复盘
  • ThreeJS:光线投射与3D场景交互
  • docker挂载数据卷-以nginx为例
  • Docker-compose部署Fastapi项目
  • Eigen求解线性方程组
  • 7、Java基本数据类型的使用细节探讨(超详细版本)
  • MFC实现点击列表头进行排序
  • 用龙梦迷你电脑福珑2.0做web服务器
  • 秋招后端开发面试题 - JVM类加载机制
  • OceanBase 分布式数据库【信创/国产化】- OceanBase 配置项和系统变量概述
  • 单单单单单の刁队列
  • 电脑windows系统压缩解压软件-Bandizip
  • 图片公式识别@文档公式识别@表格识别@在线和离线OCR工具
  • Java高阶私房菜:JVM分代收集算法介绍和各垃圾收集器原理分解
  • 为什么IB损失要在100epochs后再用?
  • 《Video Mamba Suite》论文笔记(4)Mamba在时空建模中的作用
  • 【备战软考(嵌入式系统设计师)】10 - 软件工程基础
  • 随手笔记-GNN(朴素图神经网络)
  • C 语言指针怎么理解?
  • HTTP协议:通信机制、特点及实践应用
  • Leetcode—289. 生命游戏【中等】
  • 系统运维(虚拟化)
  • Linux域名解析
  • 树形结构和列表的区别
  • Go中json的解析和反解析