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

Fluent Python 笔记 第 9 章 符合 Python 风格的对象

得益于 Python 数据模型,自定义类型的行为可以像内置类型那样自然。实现如此自然的行为,靠的不是继承,而是鸭子类型(duck typing):我们只需按照预定行为实现对象所需的方法即可。

9.1 对象表示形式

实现 __repr____str__ 特殊方法,为 repr()str() 提供支持。

9.2 再谈向量类

from array import array
import mathclass Vector2d:typecode = 'd'  # typecode 是类属性,在 Vector2d 实例和字节序列之间转换时使用。def __init__(self, x, y):self.x = float(x)  # 把 x 和 y 转换成浮点数,尽早捕获错误self.y = float(y)def __iter__(self):  #把 Vector2d 实例变成可迭代的对象,这样才能拆包  也可以写成yield self.x; yield.self.yreturn (i for i in (self.x, self.y))def __repr__(self):  # 使用 {!r} 获取各个分量的表示形式,然后插值,构成一个字符串;因为Vector2d 实例是可迭代的对象,所以 *self 会把 x 和 y 分量提供给 format 函数class_name = type(self).__name__return '{}({!r}, {!r})'.format(class_name, *self)def __str__(self):return str(tuple(self))def __bytes__(self):return (bytes([ord(self.typecode)]) + bytes(array(self.typecode, self)))def __eq__(self, other):  # 拿 Vector2d 实例与其他具有相同数值的可迭代对象相比,结果也是 True (如Vector(3, 4) == [3, 4])。这个行为可以视作特性,也可以视作缺陷。return tuple(self) == tuple(other)def __abs__(self):return math.hypot(self.x, self.y)def __bool__(self):return bool(abs(self))

9.3 备选构造方法

@classmethod
def frombytes(cls, octets):typecode = chr(octets[0])memv = memoryview(octets[1:]).cast(typecode)return cls(*memv)

9.4 classmethod 与 staticmethod

classmethod

前面展示了它的用法:定义操作类,而不是操作实例的方法。 classmethod 改变了调用方法的方式,因此类方法的第一个参数是类本身,而不是实例。 classmethod 最常见的用途是定义备选构造方法,按照约定,类方法的第一个参数名为 cls(但是 Python 不介意具体怎么命名)。

staticmethod

装饰器也会改变方法的调用方式,但是第一个参数不是特殊的值。其实,静态方法就是普通的函数,只是碰巧在类的定义体中,而不是在模块层定义。

9.5 格式化显示

>>> format(42, 'b')  # 'x'是十六进制
'101010'
>>> format(2/3, '.1%')
'66.7%'
# 在Vector2d类中定义
def __format__(self, fmt_spec=''):components = (format(c, fmt_spec) for c in self) #return '({}, {})'.format(*components) #>>> format(v1, '.2f')
'(3.00, 4.00)'
>>> format(v1, '.3e')
'(3.000e+00, 4.000e+00)'
def __format__(self, fmt_spec=''): if fmt_spec.endswith('p'):fmt_spec = fmt_spec[:-1]coords = (abs(self), self.angle())outer_fmt = '<{}, {}>'else:coords = selfouter_fmt = '({}, {})'components = (format(c, fmt_spec) for c in coords)return outer_fmt.format(*components)>>> format(Vector2d(1, 1), 'p')
'<1.4142135623730951, 0.7853981633974483>'
>>> format(Vector2d(1, 1), '.3ep')
'<1.414e+00, 7.854e-01>'
>>> format(Vector2d(1, 1), '0.5fp')
'<1.41421, 0.78540>'

9.6 可散列的 Vector2d

把 x 和 y 分量设为只读特性

class Vector2d:typecode = 'd'def __init__(self, x, y):self.__x = float(x)  # 两个前导下划线(尾部没有下划线,或者有一个下划线),把属性标记为私有的,但不符合建议self.__y = float(y)@property  # @property 装饰器把读值方法标记为特性。def x(self):return self.__x@propertydef y(self):return self.__ydef __iter__(self):return (i for i in (self.x, self.y))

最好使用位运算符异或(^)混合各分量的散列值。

    def __hash__(self):return hash(self.x) ^ hash(self.y)

9.7 Python 的私有属性和“受保护的”属性

有人编写了一个名为 Dog 的类,这个类的内部用到了 mood 实例属性,但是没有 将其开放。现在,你创建了 Dog 类的子类:Beagle。如果你在毫不知情的情况下又创建了名为 mood 的实例属性,那么在继承的方法中就会把 Dog 类的 mood 属性覆盖掉。这是个难以调试的问题。为了避免这种情况,如果以 __mood 的形式(两个前导下划线,尾部没有或最多有一个下划线)命名实例属性,Python 会把属性名存入实例的 __dict__ 属性中,而且会在前面加上一个下划线和类名。因此,对 Dog 类来说,__mood 会变成 _Dog__mood;对 Beagle 类来说,会变成 _Beagle__mood。这个语言特性叫名称改写(name mangling)。

不过,只要知道改写私有属性名的机制,任何人都能直接读取私有属性。

9.8 使用 slots 类属性节省空间

让解释器在元组中存储实例属性,而不用字典。在类中定义 __slots__ 属性之后,实例不能再有 __slots__ 中所列名称之外的其他属性。是用于优化的,不是为了约束程序员。

class Vector2d:__slots__ = ('__x', '__y')

用户定义的类中默认就有 __weakref__ 属性。可是,如 果类中定义了 __slots__ 属性,而且想把实例作为弱引用的目标,那么要把 ‘__weakref__
添加到 __slots__ 中。

slots 的问题

  • 每个子类都要定义 __slots__ 属性,因为解释器会忽略继承的 __slots__ 属性。
  • 实例只能拥有 __slots__ 中列出的属性,除非把 ‘__dict__’ 加入 __slots__ 中(这样做就失去了节省内存的功效)。
  • 如果不把 ‘__weakref__’ 加入 __slots__,实例就不能作为弱引用的目标。

与其他优化措施一样,仅当权衡当下的需求并仔细搜集资料后证明确实有必要时,才应该使用 __slots__ 属性。

9.9 覆盖类属性

如果为不存在的实例属性赋值,会新建实例属性。假如我们为 typecode 实例属性赋值,那么同名类属性不受影响。然而,自此之后,实例读取的 self.typecode 是实例属性 typecode,也就是把同名类属性遮盖了。借助这一特性,可以为各个实例的 typecode 属性定制不同的值。

类属性是公开的,因此会被子类继承,于是经常会创建一个子类,只用于定制类的数据属性。

相关文章:

Fluent Python 笔记 第 9 章 符合 Python 风格的对象

得益于 Python 数据模型&#xff0c;自定义类型的行为可以像内置类型那样自然。实现如此自然的行为&#xff0c;靠的不是继承&#xff0c;而是鸭子类型(duck typing)&#xff1a;我们只需按照预定行为实现对象所需的方法即可。 9.1 对象表示形式 实现 __repr__ 和 __str__ 特…...

档案管理数字化,成功的领导者,往往只问这3个问题

随着数字经济时代的到来&#xff0c;信息技术的更迭演进&#xff0c;逐渐改变了企业的办公业务流程&#xff0c;传统的办公业务模式已不能满足当前的企业业务需求。数字化转型成为当下企业的必选项。随着公司部门架构的日益复杂&#xff0c;流程繁多&#xff0c;产生海量的企业…...

自学软件测试从哪里开始?给还在迷茫的人一条出路

这两天和朋友谈到软件测试的发展&#xff0c;其实软件测试已经在不知不觉中发生了非常大的改变&#xff0c;前几年的软件测试行业还是一个风口&#xff0c;随着不断地转行人员以及毕业的大学生疯狂地涌入软件测试行业&#xff0c;目前软件测试行业“缺口”已经基本饱和。当然&a…...

配置MyBatis Plus 的分页查询功能

配置MyBatis Plus 的分页查询功能一. 回顾Mysql分页查询二. 配置MyBatis Plus 分页功能2.1 定义分页拦截器2.2 进行分页查询 selectPage()三. 开启MyBatis Plus的运行日志一. 回顾Mysql分页查询 limit 是MySQL当中特有的&#xff01;其他数据库没有&#xff01;不通用&#xf…...

Solon2 开发之插件,四、插件热插拔管理机制(H-Spi)

插件热插拔管理机制&#xff0c;简称&#xff1a;H-Spi。是框架提供的生产时用的另一种高级扩展方案。相对E-Spi&#xff0c;H-Spi 更侧重隔离、热插热拔、及管理性。 应用时&#xff0c;是以一个业务模块为单位进行开发&#xff0c;且封装为一个独立插件包。 1、特点说明 所…...

从react源码看hooks的原理

React暴露出来的部分Hooks //packages/react/src/React.js export {...useCallback,useContext,useEffect,useLayoutEffect,useMemo,useReducer,useRef,useState,... }功能描述 useState、useReducer: 状态值相关useEffect、useLayoutEffect: 生命周期相关useContext: 状态共…...

空间尺寸对迭代次数的影响

( A, B )---3*30*2---( 1, 0 )( 0, 1 ) ( A, B )---4*30*2---( 1, 0 )( 0, 1 ) 做4个训练集尺寸分别为3行3列&#xff0c;3行4列&#xff0c;4行3列和2行4列的网络。简写为3*3&#xff0c;3*4&#xff0c;4*3&#xff0c;2*4. 保持这4个网络差值结构的形态一致&#xff0c;…...

mininet+flowvisor+floodlight实现网络切片功能

ininetflowvisorfloodlight实现网络切片功能 这个项目所使用的软件flowvisor 和floodlight 都已经过时了网上能找到的资料太少了&#xff0c;整个项目搭建过程中遇到的坑太多了。花了大量的的时间。 有什么问题可提出来&#xff0c;如果我会的话一定会耐心解答的 此项目主要采…...

【C++】十分钟带你入门C++

目录零 内容概括一 C关键字二 命名空间2.1 命名空间定义2.2 命名空间的使用三 C输入和输出四 缺省参数4.1 缺省参数的概念4.2 缺省参数分类五 函数重载5.1 函数重载的概念六 引用6.1 引用概念6.2 引用特性6.3 常引用6.4 使用场景6.5 效率比较6.6 引用和指针的区别七 内联函数7.…...

kettle利用excel文件增量同步一个库的数据(多表一次增量同步)

利用excel文件增量同步一个库的数据 现在有sqlserver和mysql两个库上的表在进行同步&#xff0c;mysql上的是源表&#xff0c;sqlserver上是目标表。 mysql : sqlserver : 可以看到sqlserver上表的最近一次同步日期分别是 pep表&#xff1a; 2022-10-23 14:19:00.000 stu_…...

面试题:android中A Activity 打开B Activity,为什么A Activity的onStop()方法最后被调用

如下是一段典型的Activity间切换的日志&#xff0c;从A Activity切换到B Activity&#xff1a;10-17 20:54:42.247: I/com.example.servicetest.AActivity(5817): onCreate() 1166919192 taskID66 10-17 20:54:42.263: I/com.example.servicetest.AActivity(5817): onStart()…...

百度版本gactgpt即将来临,gpt人工智能机器横空出世

百度版本gactgpt即将来临&#xff0c;gpt人工智能机器横空出世&#xff0c;“一言”为定&#xff01;百度版ChatGPT确认&#xff01;李彦宏OKR曝光&#xff0c;率先应用于收索业务 gactCBT 大获&#xff0c;当下极有可能成为人工智能的 iPhone 时刻。为了在这场人工智能竞赛中…...

【python--networkx】函数说明+代码讲解

【Python–NetworkX】函数说明代码讲解 文章目录【Python--NetworkX】函数说明代码讲解1. 介绍1.1 前言1.2 图的类型&#xff08;Graph Types&#xff09;1.3 常用方法2. 代码示例1. 介绍 1.1 前言 NetworkX是复杂网络研究领域中的常用Python包。 1.2 图的类型&#xff08;G…...

【Jqgrid分页勾选保存】三步实现表格分页勾选(取消勾选)保存(附源码)

目录1、创建临时存储数组&#xff0c;初始化赋值2、单行选中与取消&#xff0c;调整数组3、全选与取消全选&#xff0c;调整数组4、输出数组保存5、片尾彩蛋【写在前面】表格可以说是在我们的web页面中是最常见的&#xff0c;之前我们介绍过layui表格翻页勾选的实现过程&#x…...

Appium移动自动化测试——app控件获取之uiautomatorviewer

下载手机YY http://yydl.duowan.com/mobile/yymobile_client-android/5.4.2/yymobile_client-5.4.2-881.apk 若链接失效&#xff0c;请自行百度 新建maven空白工程 前置条件&#xff1a;安装eclipse&#xff0c;及其maven插件&#xff0c;请自行百度 新建的工程如下&#xf…...

webpack、vite、vue-cli、create-vue 的区别

webpack、vite、vue-cli、create-vue 的区别 首先说结论 Rollup更适合打包库&#xff0c;webpack更适合打包项目应用&#xff0c;vite基于rollup实现了热更新也适合打包项目。 功能工具工具脚手架vue-clicreate-vue构建项目vite打包代码webpackrollup 脚手架:用于初始化&#…...

数据结构——TreeMap、TreeSet与HashMap、HashSet

目录 一、Map 1、定义 2、常用方法 3、注意 二、TreeMap 三、HashMap 1、定义 2、冲突定义 3、冲突避免方法——哈希函数设计 &#xff08;1&#xff09;、直接定制法(常用) &#xff08;2&#xff09;、除留余数法(常用) &#xff08;3&#xff09;、平方取中法 &…...

Spring Boot学习篇(十三)

Spring Boot学习篇(十三) shiro安全框架使用篇(五) 1 准备工作 1.1 在SysUserMapper.xml中书写自定义标签 <select id"findRoles" resultType"string">select name from sys_role where id (select roleid from sys_user_role where userid (S…...

微软Bing的AI人工只能对话体验名额申请教程

微软Bing 免费体验名额申请教程流程ChatGPT这东西可太过火了。国外国内&#xff0c;圈里圈外都是人声鼎沸。微软&#xff0c;谷歌&#xff0c;百度这些大佬纷纷出手。连看个同花顺都有GPT概念了&#xff0c;搞技术&#xff0c;做生意的看来都盯上了 流程 下面就讲一下如何申…...

怎么打造WhatsApp Team?SaleSmartly(ss客服)告诉你

关键词&#xff1a;WhatsApp Team SaleSmartly&#xff08;ss客服&#xff09; 您是否正在寻找一种让您的团队能够在 WhatsApp协作消息传递的解决方案?拥有了 WhatsApp Team&#xff0c;不仅效率提升&#xff0c;还可以在智能聊天工具中比如SaleSmartly&#xff08;ss客服&…...

网络六边形受到攻击

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 抽象 现代智能交通系统 &#xff08;ITS&#xff09; 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 &#xff08;…...

Lombok 的 @Data 注解失效,未生成 getter/setter 方法引发的HTTP 406 错误

HTTP 状态码 406 (Not Acceptable) 和 500 (Internal Server Error) 是两类完全不同的错误&#xff0c;它们的含义、原因和解决方法都有显著区别。以下是详细对比&#xff1a; 1. HTTP 406 (Not Acceptable) 含义&#xff1a; 客户端请求的内容类型与服务器支持的内容类型不匹…...

汽车生产虚拟实训中的技能提升与生产优化​

在制造业蓬勃发展的大背景下&#xff0c;虚拟教学实训宛如一颗璀璨的新星&#xff0c;正发挥着不可或缺且日益凸显的关键作用&#xff0c;源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例&#xff0c;汽车生产线上各类…...

python如何将word的doc另存为docx

将 DOCX 文件另存为 DOCX 格式&#xff08;Python 实现&#xff09; 在 Python 中&#xff0c;你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是&#xff0c;.doc 是旧的 Word 格式&#xff0c;而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...

Linux云原生安全:零信任架构与机密计算

Linux云原生安全&#xff1a;零信任架构与机密计算 构建坚不可摧的云原生防御体系 引言&#xff1a;云原生安全的范式革命 随着云原生技术的普及&#xff0c;安全边界正在从传统的网络边界向工作负载内部转移。Gartner预测&#xff0c;到2025年&#xff0c;零信任架构将成为超…...

Python爬虫(一):爬虫伪装

一、网站防爬机制概述 在当今互联网环境中&#xff0c;具有一定规模或盈利性质的网站几乎都实施了各种防爬措施。这些措施主要分为两大类&#xff1a; 身份验证机制&#xff1a;直接将未经授权的爬虫阻挡在外反爬技术体系&#xff1a;通过各种技术手段增加爬虫获取数据的难度…...

Psychopy音频的使用

Psychopy音频的使用 本文主要解决以下问题&#xff1a; 指定音频引擎与设备&#xff1b;播放音频文件 本文所使用的环境&#xff1a; Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...

网络编程(UDP编程)

思维导图 UDP基础编程&#xff08;单播&#xff09; 1.流程图 服务器&#xff1a;短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...

ABAP设计模式之---“简单设计原则(Simple Design)”

“Simple Design”&#xff08;简单设计&#xff09;是软件开发中的一个重要理念&#xff0c;倡导以最简单的方式实现软件功能&#xff0c;以确保代码清晰易懂、易维护&#xff0c;并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计&#xff0c;遵循“让事情保…...

Hive 存储格式深度解析:从 TextFile 到 ORC,如何选对数据存储方案?

在大数据处理领域&#xff0c;Hive 作为 Hadoop 生态中重要的数据仓库工具&#xff0c;其存储格式的选择直接影响数据存储成本、查询效率和计算资源消耗。面对 TextFile、SequenceFile、Parquet、RCFile、ORC 等多种存储格式&#xff0c;很多开发者常常陷入选择困境。本文将从底…...