柯里化与无参装饰器

柯里化

柯里化的概念:柯里化(Currying)在Python中是一种编程技术,它将原本接受多个参数的函数转换为一系列接受单个参数的函数。这种方法以逻辑学家Haskell Curry的名字命名。

简而言之就是将一次函数调用变成先放入一个参数得到的中间函数对象,然后再对中间函数对象进行传参,这样可以将多参数函数变成多个单参数函数。

def add(x):
    def inner(y,z):
        return x+y+z
    return inner

print(add(1)(2,3))

在第一个例子中,我们先将x传入得到一个带有x参数的函数对象,然后再对这个函数对象继续传入y,z两个参数,柯里化的程度是取决于我们的需要的,我们当然也可以将其分成三个函数,如下图

def add(x):
    def innner(y):
        def inner_1(z):
            return x+y+z
        return inner_1
    return innner

print(add(1)(2)(3))

 现在,我们对柯里化有了一定了解,但我们该怎么把柯里化和装饰器关联在一起呢?

装饰器

你可以顾名思义,装饰器就是装饰函数用的,函数太单调?我们可以给它加一些功能让它尽可能丰满一些,为了丰富函数,有必要引入柯里化吗,我直接在函数里写不就行了?这就要考虑到代码侵入性问题了,我们将非业务代码(装饰代码)写在函数里,这就产生了业务与非业务代码的纠缠,这不利于后期代码的修改,何况,如果我想为多个函数进行装饰,难道我要一个一个copy过去?这显然不切实际,所以我们运用了函数的思想,把装饰代码封装到一个函数中,然后再将其应用在目标函数上,这实际上是将函数当作参数传入一个函数(高阶函数),而柯里化在其中的作用就是分割,它将装饰函数应用在目标函数然后返回一个装饰过的目标函数,但这个过程不会影响原目标函数,这可能有一些抽象,接下来我们应用实例来说明。

def add(x,y):
    return x+y

def logger(fn):
    def wrapper(*args,**kwargs):
        print("{} function is called. {},{}".format(fn.__name__,args,kwargs))
        ret = fn(*args,**kwargs)
        return ret
    return wrapper

add = 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 ret
    return wrapper

@logger
def add(x,y):
    return x+y
print(add(1,2))

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

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/607265.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Segmentation fault (core dumped)排查

先泼盆冷水,这个问题比较棘手,有的能通过重装opencv相关包修复,有的可能还是直接换一个没问题的环境比较快…… 我最后是没有解决的,折腾了几个小时后,还是听同事的话,把docker镜像重启了,幸好…

day04—java基础之方法详解

方法概述 方法是具有特定功能的代码集合,由于我们是把重复的代码写到方法当中,以后要用直接调用方法即可,不需要再写一遍了。代码相当于只写了一遍。所以可以提高代码的复用性。如果要修改代码,我们也只要修改一处即可&#xff0…

JavaSwing技术实现一个电子表程序

使用JavaSwing技术实现一个简单的电子表盘,如下所示。 下载链接 有兴趣的读者可以点击链接下载,博主承诺绝对真实有效。

bert-NER 转化成 onnx 模型

保存模型 加载模型 from transformers import AutoTokenizer, AutoModel, AutoConfigNER_MODEL_PATH ./save_model ner_tokenizer AutoTokenizer.from_pretrained(NER_MODEL_PATH) ner_config AutoConfig.from_pretrained(NER_MODEL_PATH) ner_model AutoModelForTokenCl…

VIsualGDB : 快速入门系列

《VisualGDB : 解决编码导致的编译错误》 《VisualGDB : 在windows上开发和调试Linux代码(一)》 《VisualGDB:为Linux项目添加系统依赖库》 《VisualGDB:Linux动态库项目创建、编译及库的使用》 《VisualGD…

Web3空投入门:如何增加空投成功的几率

今天分享空投如何避免限制以提高效率,增加成功几率,首先我们来了解什么是空投加密,有哪些空投类型。 一、什么是空投加密? 加密货币空投是一种营销策略,包括向用户的钱包地址发送免费的硬币或代币。 加密货币项目使用…

Linux网络编程(三)IO复用三 epoll系统调用

三、epoll系统调用 epoll是Linux特有的I/O复用函数。它在实现和使用上与select、poll有很大差异。 epoll使用一组函数来完成任务,而不是单个函数epoll把用户关心的文件描述符上的事件放在内核里的一个事件表中,从而无须像select和poll那样每次调用都要…

Python从0到POC编写--实用小脚本

UrlCheck: 假设我们要对一份 url 列表进行访问是不是 200 , 量多的话肯定不能一个一个去点开看, 这个时候我们可以借助脚本去判断, 假如有一份这样的列表, 这份列表呢,奇奇怪怪,有些写错了…

Golang——Strconv包

func ParseBool(str string) (value bool, err error) strconv包实现了基本数据类型与其字符串表示的转换,主要有以下常用函数:Atoi(),Itoa(),parse系列函数,format系列函数,append系列函数。 1.1 string与…

6份不用辞职就能赚钱的副业,上班族必看!

在这个经济浪潮中,生活成本的上升与工资增长的缓慢形成了鲜明对比。对于许多上班族来说,寻找额外收入的途径显得尤为迫切。 今天,就让我们一起探索那些适合在业余时间开展的副业,为你的财务自由之路添砖加瓦。 1. 闲鱼二手手机售卖…

SEO之高级搜索指令(三)

初创企业需要建站的朋友看这篇文章,谢谢支持: 我给不会敲代码又想搭建网站的人建议 新手上云 (接上一篇。。。。) 11、link: link:也是SEO 常用的指令,用来搜索某个url的反向链接,既包括内部链接&#xf…

python编程“常识”【pip安装路径、计算、pycharm中的terminal运行前面的PS修改成自己环境】

一、默认的pip install包路径: pip show pip 二、计算 打开cmd,输入: ipython 例如你要计算2的13次方: ok. 三、pycharm中的terminal运行前面的PS修改成自己环境 未修改前: 修改过程: 打开设置找到too…

渗透之sql注入---宽字节注入

宽字节注入原理: 宽字节注入就是在对用户输入进行处理时,将编码方式改变,当某些关键字符被过滤(转义)时,我们可以使用其他的编码在被转义的字符前面,这样就可以组成一个新的字符从而来实现绕过…

【备战软考(嵌入式系统设计师)】10 - 软件工程基础

这一部分的内容是概念比较多,不要理解,去感受。 涉及的知识点是嵌入式系统开发和维护的部分,也就是和管理相关的,而不是具体如何进行嵌入式系统开发的细节。 系统开发生命周期 按照顺序有下面几个阶段,我们主要要记…

WPF容器控件之WrapPanel、布局控件

WrapPanel: 换行panel 子元素进行换行&#xff0c;当子元素的宽度或者高度超出了父元素&#xff0c;才进行换行。高度超出父元素的高度 也会另起一列 属性 Orientation布局方式 实例 <WrapPanel Orientation"Horizontal"><Label>C# 是从 C/C 衍生出来的…

zabbix动作执行命令失效不起作用?

1. zabbix在web界面设置完主机组&#xff0c;主机&#xff0c;监控项&#xff0c;触发器&#xff0c;动作之后 监控项监控到了&#xff0c;触发器触发动作&#xff0c;但是执行的指令不起作用 流程 在zabbix-agent端将nginx服务down掉&#xff0c;zabbix会自动监控并执行重启的…

一文了解Memcache内存分配机制及stats参数

一、Memcache内存分配机制 了解memcached必须了解的三个单位&#xff1a;page、slabs、chunk。 1.1、Page Page为内存分配的最小单位,Memcached的内存分配以page为单位&#xff0c;默认情况下一个page是1M&#xff0c;可以通过-I参数在启动时指定。如果需要申请内存 时&#…

NeRF算法

目录 算法介绍 基本原理 1. 体渲染 2. 多层感知机&#xff08;MLP&#xff09; 3. 位置编码 4. 两阶段层次化体采样 实验展示 代码解析 算法介绍 NeRF&#xff08;Neural Radiance Fields&#xff09;是一种用于从2D图像中重建3D场景的神经网络模型。它通过训练一个深度…

sourceTree push失败

新电脑选择commit and push&#xff0c;报错了&#xff0c;不过commit成功&#xff0c;只不过push失败了。 原因是这个&#xff0c;PuTTYs cache and carry on connecting. 这里的ssh选择的是 PuTTY/Plink&#xff0c;本地没有这个ssh密钥&#xff0c;改换成openSSH&#xff…

SRM系统供应链库存协同提升企业服务水平

SRM系统供应链库存协同是一种以提高供应链整体效率和竞争力为目标的管理方法。它涉及到企业与供应商之间的紧密合作&#xff0c;以实现库存优化、成本降低、风险分担和灵活响应市场变化等目标。 一、SRM供应链库存协同的概念和特点 SRM供应链库存协同是指企业与供应商之间通过…
最新文章