流畅的python--第七章

news/2025/3/17 6:56:58/文章来源:https://www.cnblogs.com/bonne-chance/p/18233496

把函数视为对象

在python中,函数是一等对象。编程语言研究人员把“一等对象”定义为满足以下条件的程序实体:

  • 在运行时创建;
  • 能赋值给变量或数据结构中的元素;
  • 能作为参数传给函数;
  • 能作为函数的返回结果。
    示例7-1 创建并测试一个函数,读取函数的__doc__属性,再检查函数的类型

🚩 __doc__属性用于生成对象的帮助文本.

示例7-2 通过其他名称使用factorial函数,再把factorial函数作为参数传递

🚩 示例7-2展示了函数对象的“一等”本性。可以把factorial函数赋值给变量fact,然后通过变量名调用。还可以把factorial函数作为参数传给map函数。map(function, iterable)调用会返回一个可迭代对象,所含的项是把第一个参数(一个函数)应用到第二个参数(一个可迭代对象,这里是range(11))中各个元素上得到的结果。

高阶函数

接受函数为参数或者把函数作为结果返回的函数是高阶函数(higher-oder function)。示例7-2中的map函数就是一例。此外,内置函数sorted也是:通过可选的key参数提供一个函数,应用到每一项上进行排序。

示例7-3 根据单词长度排序一个列表

🚩 任何单函数都可以作为key参数的值。例如,为了创建押韵字典,可以把各个单词反过来拼写,然后排序。

示例7-4 根据反向拼写排序一个单词列表

🚩 在函数式编程范式中,最为人熟知的高阶函数有map、filter、reduce和apply(python3已经废弃),可以编写fn(*args, **kwargs).

mapfilterreduce的现代替代品。函数式语言通常会提供mapfilterreduce这3个高阶函数,在python3中,map和filter还是内置函数,但是由于引入了列表推导式和生成器表达式,因此二者就变得没那么重要了。列表推导式或生成器表达式兼具mapfilter这两个函数的功能,而且代码可读性更高。
示例7-5 计算阶乘列表:mapfilter与列表推导式对比

示例7-6 使用reducesum计算0——99的整数之和

🚩 sum和reduce的整体运作方式是一样的,即把某个操作连续应用到序列中的项上,累计前一个结果,把一系列值规约成一个值

内置的规约函数还有allany

  • all(iterable) iterable中没有表示假值的元素时返回Trueall([])返回True
  • any(iterable) 只要iterable中有元素是真值就返回Trueany([])返回False

匿名函数

lambda关键字使用python表达式创建匿名函数。然而,受python简单的句法限制,lambda函数的主体只能是纯粹的表达式,不能有whiletry等其他语句。赋值语句=也不能出现在lambda函数的主体中,但是可以有海象运算符:=,但是这种语句太过复杂,可读性差,因此建议重构。
示例7-7使用lambda表达式反转拼写,然后依次给单词列表排序。

9种可调用对象

除了函数,调用运算符(())还可以应用到其他对象上,如果想判断对象能否调用,可以使用内置的callable()函数。

  • 用户定义的函数
    使用def语句或lambda表达式创建的函数
  • 内置函数
    使用C语言(Cpython)实现的函数,例如lentime.strftime
  • 内置方法
    使用C语言实现的方法,例如 dict.get
  • 方法
    在类主体中定义的函数

  • 调用类时运行类的 __new__ 方法创建一个实例,然后运行
    __init__ 方法,初始化实例,最后再把实例返回给调用方。Python
    没有 new 运算符,调用类就相当于调用函数
  • 类的实例
    如果类定义了 __call__ 方法,那么它的实例可以作为函数调用。
  • 生成器函数
    主体中有 yield 关键字的函数或方法。调用生成器函数返回一个
    生成器对象
  • 原生协程函数
    使用 async def 定义的函数或方法。调用原生协程函数返回一个
    协程对象。
  • 异步生成器函数
    使用 async def定义,而且主体中有 yield 关键字的函数或方
    法。调用异步生成器函数返回一个异步生成器,供 async for 使用。

用户定义的可调用类型

不仅 Python 函数是真正的对象,而且任何 Python 对象都可以表现得像
函数。为此,只需实现实例方法 __call__
示例7-8 bingocall.py:调用BingoCage实例,从打乱顺序的列表中取出一个元素

🚩 bingo实例可以作为函数调用,而且内置函数callable()判定它是可调用对象。

从位置参数到仅限关键字参数

Python 函数最好的功能之一是提供了极为灵活的参数处理机制。与之密
切相关的是,调用函数时可以使用 * ** 拆包可迭代对象,映射各个
参数。
示例7-9 tag函数用于生成HTML标签。可以使用名为class_的仅限关键字参数传入“class”属性,这是一种变通方法,因为“class”python中的关键字。

在示例7-9中,class_参数只能通过关键字参数指定,它一定不会捕获无名位置参数。定义函数时,如果想指定仅限关键字参数,就要把它们放到前面有的参数后面。如果不想支持数量不定的位置参数,但是想支持仅限关键字参数,则可以在签名中放一个

注意,仅限关键字参数不一定要有默认值,可以像上例中的 b 那样,强
制要求传入实参。

仅限位置参数

python3.8开始,用户定义的函数签名可以指定仅限位置参数。内置函数都是如此。例如
divmod(a, b)只能使用位置参数调用,不能写成divmod(a=10, b=4)。如果想定义只接受位置参数的函数,则可以在参数列表中使用/

def divmod(a, b, /):return (a//b, a%b)

/左边均是仅限位置参数。在'/'后面,可以指定其他参数,处理方式一同往常。

支持函数式编程的包

Python 的目标不是变成函数式编程语言,但是得
益于一等函数、模式匹配,以及 operatorfunctools 等包的支
持,其对函数式编程风格也可以“信手拈来”。

  • operator模块
    在函数式编程中,经常需要把算术运算符当作函数使用。例如,不使用
    递归计算阶乘。求和可以使用 sum 函数,求积则没有这样的函数。可以
    使用 reduce 函数(参见“mapfilterreduce 的现代替代品”一
    节),但是需要一个函数来计算序列中两项之积。
    示例 7-13 使用itemgetter排序一个元组列表

    示例7-14使用attrgetter处理前文定义的具名元组

  • 使用functools.partial冻结参数
    functools 模块提供了一系列高阶函数,比如 7.3 节mapfilter
    reduce 的现代替代品”中用过的 reduce。另外一个值得关注的函数是
    partial,它可以根据提供的可调用对象产生一个新可调用对象,为原
    可调用对象的某些参数绑定预定的值。使用这个函数可以把接受一个或
    多个参数的函数改造成需要更少参数的回调的 API
    示例7-16 使用partial 把一个双参数函数改造成只需要一个参
    数的可调用对象

    示例7-17 使用partial构建一个便利的Unicode规范化函数

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

OA-SLAM 笔记

4.1 基于 ORB-SLAM2 (tracking, local mapping, loop closure) , 增加了 针对于 objects 的模块。这些模块使用 the ellipse/ellipsoid modeling framework, 和 points 使用相同的策略, 即在 frames 上跟踪 objects, 以 3D 的方式估计,插入到地图,然后不断优化。object tr…

iLogtail 2.0 重大升级,端上支持 SPL

SLS 推出了 SPL(SLS Processing Language)语法,以此统一查询、端上处理、数据加工等的语法,保证了数据处理的灵活性。iLogtail 作为日志、时序数据采集器,在 2.0 版本中,全面支持了 SPL 。作者:太业 流式处理语言发展早期流式处理概念:20 世纪 70 年代,编程语言如 APL…

提供高达 58 Gbps 的收发器速率、AGFA023R31C2E1VB/AGFA023R31C2I1V/AGFA023R31C2I2VB现场可编程门阵列 (FPGA)

Agilex F 系列设备提供高达 58 Gbps 的收发器速率、支持多种精度的定点和浮点运算的高级数字信号处理 (DSP) 模块,以及高性能加密块。Agilex 7 FPGA产品系列包括业界最高性能的FPGA和SoC。英特尔 Agilex 7 FPGA和SoC由高性能的F系列、I系列和M系列FPGA组成,为要求最高的应用提…

JA4指纹了解

原文来自:https://mp.weixin.qq.com/s/Vo57J6l7WEt7L2bF_EAfbA https://xz.aliyun.com/t/14054?time__1311=mqmx9DBG0QD%3DNGNDQiiQGk0G8UAfWRi8rD&alichlgref=https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3DiCpL-H6nh6F3hHSqKNxdmugqoq3VxxR00WtgPIO6P2n4QKqCs9QZmOV5veT…

wsl安装教程

关于WLS的介绍1.什么是WSL?2 双系统的方法比较3 WSL1与WSL2比较 方法一: 传统手动安装1.1 windows系统版本查看及更新1.2 启用适用于Linux的Windwos子系统1.3 启用虚拟机功能1.4 重启电脑1.5 下载Linux内核更新包1.6 安装 Linux 分发版 方法二:命令符自动安装 (一行命令搞定…

Redis-4-持久化

Redis持久化 1.1 为什么 Redis是基于内存的,不保存的话,应用停止了后数据就不在了。 持久化的诉求,主要是解决以下问题: 防止数据丢失 Redis 是一个内存数据库,数据主要存储在内存中。如果没有持久化机制,一旦服务器宕机或重启,内存中的所有数据都会丢失。通过持久化,R…

Nacos配置

Nacos注册中心 目前开源的注册中心框架有很多,国内比较常见的有:Eureka:Netflix公司出品,目前被集成在SpringCloud当中,一般用于Java应用 Nacos:Alibaba公司出品,目前被集成在SpringCloudAlibaba中,一般用于Java应用 Consul:HashiCorp公司出品,目前集成在SpringCloud…

RK3308B WIFI

修改 WIFI 型号 ./device/rockchip/rk3308/rockchip_rk3308b_64bit_defconfig修改设备树 根节点 ---> wireless-wlanwireless-wlan {compatible = "wlan-platdata";rockchip,grf = <&grf>;pinctrl-names = "default";pinctrl-0 = <&wi…

WPF初学习(一)

控件模板 控件模板又包括ControlTemplate和ItemsPanelTemplate ControlTemplate(控件模板)不仅是用于来定义控件的外观、样式, 还可通过控件模板的触发器(ControlTemplate.Triggers)修改控件的行为、响应动画等。 样式定义了一些基础的样式, 背景颜色、字体颜色、边框大小、垂直…

一文搞懂Kafka,在项目里面更加得心应手的使用

1. kafka关键概念与术语 1.1 简单的例子说明kafka的使用场景 Apache kafka 是消息中间件的一种,我发现很多人不知道消息中间件是什么,在开始学习之前,我这边就先简单的解释一下什么是消息中间件,只是粗略的讲解,目前kafka已经可以做更多的事情。 举个例子:生产者消费者,…

回归模型的算法性能评价

一、概述 在一般形式的回归问题中,会得到系列的预测值,它们与真实值(ground truth)的比较表征了模型的预测能力,为有效量化这种能力,常见的性能评价指标有可解释方差(EVS)、平均绝对误差(MAE)、均方误差(MSE)、均方根误差(RMSE)、决定系数(R2)等。值得一提的是…

还在拼冗长的WhereIf吗?100行代码解放这个操作

通常我们在做一些数据过滤的操作的时候,经常需要做一些判断再进行是否要对其进行条件过滤。普通做法 最原始的做法我们是先通过If()判断是否需要进行数据过滤,然后再对数据源使用Where来过滤数据。 示例如下: if(!string.IsNullOrWhiteSpace(str)) {query = query.Where(a =…