Fluent Python 笔记 第 5 章 一等函数
在 Python 中,函数是一等对象。编程语言理论家把“一等对象”定义为满足下述条件的程 序实体:
- 在运行时创建
- 能赋值给变量或数据结构中的元素 • 能作为参数传给函数
- 能作为函数的返回结果
5.1 把函数视作对象
会用 map
。
5.2 高阶函数
接受函数为参数,或者把函数作为结果返回的函数是高阶函数(higher-order function)。
map、filter 和 reduce 的现代替代品
>>> list(map(fact, range(6)))
[1, 1, 2, 6, 24, 120]
>>> [fact(n) for n in range(6)]
[1, 1, 2, 6, 24, 120]
>>> list(map(factorial, filter(lambda n: n % 2, range(6))))
[1, 6, 120]
>>> [factorial(n) for n in range(6) if n % 2
[1, 6, 120]
all(iterable)
如果 iterable 的每个元素都是真值,返回 True;all([]) 返回 True。
any(iterable)
只要 iterable 中有元素是真值,就返回 True;any([]) 返回 False。
5.3 匿名函数
lambda 函数的定义体中不能赋值,也不能使用 while 和 try 等Python 语句。
5.4 可调用对象
如果想判断对象能否调用,可以使用内置的 callable() 函数。
5.5 用户定义的可调用类型
实现 __call__
方法
5.6 函数内省
5.7 从定位参数到仅限关键字参数
看懂下面这个怎么传。
def tag(name, *content, cls=None, **attrs):print('name:', name)print('content:', content)print('cls:', cls)print('attrs:', attrs)
5.8 获取关于参数的信息
内省:好像是指调用函数之前就知道这个函数需要什么参数,有没有默认参数。
函数对象有个 __defaults__
属性,它的值是一个元组,里面保存着定位参数和关键字参 数的默认值。仅限关键字参数的默认值在 __kwdefaults__
属性中。然而,参数的名称在 __code__
属性中,它的值是一个 code 对象引用,自身也有很多属性。
参数名称在 __code__.co_varnames
中,不过里面还有函数定义体中创建的局部变量。因此,参数名称是前 N 个字符串,N 的值由 __code__
.co_argcount 确定。顺便说一下,这里不包含前缀为 * 或 ** 的变长参数。参数的默认值只能通过它们在 __defaults__
元组中的位置确定,因此要从后向前扫描才能把参数 和默认值对应起来。在这个示例中 clip 函数有两个参数,text 和 max_len,其中一个有默认值,即 80,因此它必然属于最后一个参数,即 max_len。这有违常理。
所以使用 inspect
。
>>> from clip import clip
>>> from inspect import signature
>>> sig = signature(clip)
>>> sig # doctest: +ELLIPSIS
<inspect.Signature object at 0x...>
>>> str(sig)
'(text, max_len=80)'
>>> for name, param in sig.parameters.items():
... print(param.kind, ':', name, '=', param.default)
...
POSITIONAL_OR_KEYWORD : text = <class 'inspect._empty'>
POSITIONAL_OR_KEYWORD : max_len = 80
kind 属性的值是 _ParameterKind 类中的 5 个值之一,列举如下。 POSITIONAL_OR_KEYWORD
可以通过定位参数和关键字参数传入的形参(多数 Python 函数的参数属于此类)。 VAR_POSITIONAL
定位参数元组。
VAR_KEYWORD
关键字参数字典。
KEYWORD_ONLY
仅限关键字参数(Python 3 新增)。 POSITIONAL_ONLY
仅限定位参数;目前,Python 声明函数的句法不支持,但是有些使用 C 语言实现且不 接受关键字参数的函数(如 divmod)支持。
inspect.Signature 对象有个 bind 方法,它可以把任意个参数绑定到签名中的形参上,所用的规则与实参到形参的匹配方式一样。框架可以使用这个方法在真正调用函数前验证参数,
>>> import inspect
>>> sig = inspect.signature(tag)
>>> my_tag = {'name': 'img', 'title': 'Sunset Boulevard', ... 'src': 'sunset.jpg', 'cls': 'framed'}
>>> bound_args = sig.bind(**my_tag)
>>> bound_args
<inspect.BoundArguments object at 0x...>
>>> for name, value in bound_args.arguments.items():
... print(name, '=', value)
...
name = img
cls = framed
attrs = {'title': 'Sunset Boulevard', 'src': 'sunset.jpg'}
5.9 函数注解
函数声明中的各个参数可以在 : 之后增加注解表达式。
def clip(text:str, max_len:'int > 0'=80) -> str:
"""在max_len前面或后面的第一个空格处截断文本
"""
5.10 支持函数式编程的包
5.10.1 operator模块
operator模块为多个算术运算符提供了对应的函数,从而避免编写lambda a, b: a*b 这种平凡的匿名函数。
# 阶乘
reduce(mul, range(1, n+1))
operator 模块中还有一类函数,能替代从序列中取出元素或读取对象属性的 lambda 表达式:因此,itemgetter 和 attrgetter 其实会自行构建函数。
itemgetter(1)
的 作用与 lambda fields: fields[1]
一样。如果把多个参数传给 itemgetter,它构建的函数会返回提取的值构成的元组。itemgetter 使用 [] 运算符,因此它不仅支持序列,还支持映射和任何实现 __getitem__
方法的类。
attrgetter
与 itemgetter
作用类似,它创建的函数根据名称提取对象的属性。如果把 多个属性名传给 attrgetter
,它也会返回提取的值构成的元组。此外,如果参数名中包含 .(点号),attrgetter
会深入嵌套对象,获取指定的属性。
下面是 operator 模块中定义的部分函数(省略了以 _ 开头的名称,因为它们基本上是实现细节):
>>> [name for name in dir(operator) if not name.startswith('_')]
['abs', 'add', 'and_', 'attrgetter', 'concat', 'contains','countOf', 'delitem', 'eq', 'floordiv', 'ge', 'getitem', 'gt',
'iadd', 'iand', 'iconcat', 'ifloordiv', 'ilshift', 'imod', 'imul',
'index', 'indexOf', 'inv', 'invert', 'ior', 'ipow', 'irshift',
'is_', 'is_not', 'isub', 'itemgetter', 'itruediv', 'ixor', 'le',
'length_hint', 'lshift', 'lt', 'methodcaller', 'mod', 'mul', 'ne',
'neg', 'not_', 'or_', 'pos', 'pow', 'rshift', 'setitem', 'sub',
'truediv', 'truth', 'xor']
以 i 开头、后面是另一个运算符的那些名称(如 iadd、iand 等),对应的是增量赋值运算符(如 +=、&= 等)。如果第一个参数是可变的,那 么这些运算符函数会就地修改它;否则,作用与不带 i 的函数一样,直接返回运算结果。
methodcaller
还可以冻结部分参数。
>>> from operator import methodcaller
>>> s = 'The time has come'
>>> upcase = methodcaller('upper')
>>> upcase(s)
'THE TIME HAS COME'
>>> hiphenate = methodcaller('replace', ' ', '-')
>>> hiphenate(s)
'The-time-has-come'
5.10.2 使用functools.partial冻结参数
triple = partial(mul, 3)
triple(7)
21
triple.func # 可以访问原函数。
triple.keywords
相关文章:

Fluent Python 笔记 第 5 章 一等函数
在 Python 中,函数是一等对象。编程语言理论家把“一等对象”定义为满足下述条件的程 序实体: 在运行时创建能赋值给变量或数据结构中的元素 • 能作为参数传给函数能作为函数的返回结果 5.1 把函数视作对象 会用 map。 5.2 高阶函数 接受函数为参数࿰…...

卡尔曼滤波器与DSP实现
卡尔曼滤波器是利用系统状态方程,结合测量结果对系统状态进行进行最优估计的算法。本文介绍它的主要公式,并举例在C6000 DSP上实现。 推荐资料 KalmanFilter.NETUnderstanding Kalman Filters卡尔曼滤波与组合导航原理 “If you can’t explain it sim…...

引入QQ邮箱发送验证码进行安全校验
最近想给自己的项目在注册时加点安全校验,本想着使用短信验证码,奈何囊中羞涩只能退而求次改用QQ邮箱验证注册~ 一.需求分析 场景:用户输入自己的邮箱,点击获取验证码,后台会发送一封邮件到对应邮箱中。 分析&#x…...
【c++】数组
文章目录一维数组定义方式数组名案例案例1:元素逆置案例2:冒泡排序二维数组定义方式数组名案例:考试成绩统计数组特点: 1、每个数据元素放在一块连续的内存空间中; 2、数组中每个数据元素都是相同数据类型;…...

线程池的简单实现:Java线程池初学者必读指南
"作为一名Java开发者,是否曾经遇到过多线程并发的问题?线程数量过多时,会导致资源浪费,应用性能下降,甚至发生线程死锁的情况。那么,有没有一种方法可以有效地管理线程,避免这些问题呢&…...

【C#】[带格式的字符串] 复合格式设置字符串与使用 $ 的字符串内插 | 如何格式化输出字符串
复合格式输出 string name "Fred"; String.Format("Name {0}, hours {1:hh}", name, DateTime.Now);通过指定相同的参数说明符,多个格式项可以引用对象列表中的同一个元素。 例如,通过指定“0x{0:X} {0:E} {0:N}”等复合格式字符…...

Lecture4 反向传播(Back Propagation)
目录 1 问题背景 1.1计算图(Computational Graph) 1.2 激活函数(Activation Function)引入 1.3 问题引入 2 反向传播(Back Propagation) 2.1 为什么要使用反向传播 2.2 前馈运算(Forward Propagation…...

Power BI 筛选器函数---Window实例详解
一、Window函数 语法: Window ( <起始位置>,<起始位置类型>,<结束位置>,<结束位置类型>, [<关系>], [<OrderBy>],[空白],[PartitionBy] ) 含义: 对指定分区(PartitioinBy)中的行(关系表&…...
基础篇—如何创建css样式表,并集成到html文件中?
CSS 创建 HTML相当于一个页面的结构,CSS相当于页面的装饰,浏览器当读到一个样式表时,浏览器会根据它来格式化 HTML 文档。 如何插入样式表 插入样式表的方法有三种: 外部样式表(External style sheet)内部样式表(Internal style sheet)内联样式(Inline style)1、外…...

WindowsServer服务器系列:部署FTP文件服务
1、点击“开始”菜单,选择“服务器管理器” 2、在接下来弹出页面中选择“添加角色和功能” 3、接下来点击“下一步” 4、接下来选择“基于角色或基于功能的安装”并点击“下一步” 5、选择“从服务器池中选择服务器”并点击“下一步” 6、接下来选中“Web 服务器(II…...
华为OD机试 - 数字加减游戏(Python)| 真题+思路+代码
数字加减游戏 题目 小明在玩一个数字加减游戏,只使用加法或者减法,将一个数字 s 变成数字 t。 每个回合,小明可以用当前的数字加上或减去一个数字。 现在有两种数字可以用来加减,分别为 a,b(a!=b),其中 b 没有使用次数限制。 请问小明最少可以用多少次 a,才能将数字 s …...

【c/c++】c语言的自增操作在不同编译器的差别
示例代码 代码如下: #include <stdio.h>#define product(x) ((x)*(x))int main(void) {int i 3, j, k;j product(i); // (i) * (i)k product(i); // (i) * (i)printf("%d %d\n", j, k); }执行结果 在Ubuntu18.04下通过GCC编译和执行的结果…...

【LeetCode第 332 场周赛】
传送门 文章目录6354. 找出数组的串联值6355. 统计公平数对的数目6356. 子字符串异或查询6357. 最少得分子序列6354. 找出数组的串联值 题目 思路 前后指针 代码 class Solution { public:long long findTheArrayConcVal(vector<int>& nums) {long long res 0;i…...

【蓝桥杯单片机】Keil5中怎么添加STC头文件;从烧录软件中添加显示添加成功后新建工程时依旧找不到
蓝桥杯单片机的芯片型号:IAP15F2K61S2 添加头文件:STC15F2K60S2.H 【1】如何通过烧录软件添加STC头文件: 从ATC-ISP的Keil仿真设置中添加(同时自动下载仿真驱动)仔细阅读添加说明 KEIL5添加STC芯片库_Initdev的博客-…...

图解浏览器渲染页面详细过程
渲染详细过程 产生渲染任务,开启渲染流程 当浏览器的网络线程收到 HTML 文档后,会产生一个渲染任务,并将其传递给渲染主线程的消息队列。 在事件循环机制的作用下,渲染主线程取出消息队列中的渲染任务,开启渲染流程。…...
多线程面试题开胃菜1(5道)
一.多线程有什么用?1)发挥多核CPU 的优势随着工业的进步,现在的笔记本、台式机乃至商用的应用服务器至少也都是双核的,4 核、8 核甚至 16 核的也都不少见,如果是单线程的程序,那么在双核 CPU 上就浪费了 50…...

植物育种中广义遗传力的定义
大家好, 我是邓飞。 今天聊一下广义遗传力的计算方法。 广义遗传力定义 广义遗传力(H2H^2H2)定义为归因于基因型总体遗传变异的表型变异比例。 通常他包括三个解释:(详见我这篇博客的公式推导 回归系数 相关系数 遗…...

西瓜书读书笔记—绪论
文章目录机器学习典型的机器学习过程基本术语归纳偏好机器学习 机器学习:致力于研究如果通过计算的手段,利用经验来改善系统自身的性能 在计算机系统中,“经验” 通常以 “数据” 形式存在,因此,机器学习所研究的主要内…...

ES8——Generator函数的使用
babel工具插件下载:npm i --save babel-polyfill 引入:polyfill.js进行转码(es8->es5) 介绍 Generator函数用于生成迭代器 function * (){} yeild: 作用同return类似 {const obj function* () {yield "a";yield 12…...
德馨食品冲刺A股上市:计划募资9亿元,林志勇为实际控制人
近日,浙江德馨食品科技股份有限公司(下称“德馨食品”或“德馨饮料”)预披露更新招股书,准备在上海证券交易所主板上市。据贝多财经了解,德馨食品于2022年7月5日递交上市申请,安信证券为其保荐机构。 本次…...

网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

Unity3D中Gfx.WaitForPresent优化方案
前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...

shell脚本--常见案例
1、自动备份文件或目录 2、批量重命名文件 3、查找并删除指定名称的文件: 4、批量删除文件 5、查找并替换文件内容 6、批量创建文件 7、创建文件夹并移动文件 8、在文件夹中查找文件...
多场景 OkHttpClient 管理器 - Android 网络通信解决方案
下面是一个完整的 Android 实现,展示如何创建和管理多个 OkHttpClient 实例,分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...
将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?
Otsu 是一种自动阈值化方法,用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理,能够自动确定一个阈值,将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...

Android 之 kotlin 语言学习笔记三(Kotlin-Java 互操作)
参考官方文档:https://developer.android.google.cn/kotlin/interop?hlzh-cn 一、Java(供 Kotlin 使用) 1、不得使用硬关键字 不要使用 Kotlin 的任何硬关键字作为方法的名称 或字段。允许使用 Kotlin 的软关键字、修饰符关键字和特殊标识…...
docker 部署发现spring.profiles.active 问题
报错: org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...

以光量子为例,详解量子获取方式
光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学(silicon photonics)的光波导(optical waveguide)芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中,光既是波又是粒子。光子本…...
多模态图像修复系统:基于深度学习的图片修复实现
多模态图像修复系统:基于深度学习的图片修复实现 1. 系统概述 本系统使用多模态大模型(Stable Diffusion Inpainting)实现图像修复功能,结合文本描述和图片输入,对指定区域进行内容修复。系统包含完整的数据处理、模型训练、推理部署流程。 import torch import numpy …...

Unity UGUI Button事件流程
场景结构 测试代码 public class TestBtn : MonoBehaviour {void Start(){var btn GetComponent<Button>();btn.onClick.AddListener(OnClick);}private void OnClick(){Debug.Log("666");}}当添加事件时 // 实例化一个ButtonClickedEvent的事件 [Formerl…...