【流畅的python】第一章 Python数据模型
文章目录
- 第一章 Python 数据模型
- 1.1 python风格的纸牌
- 1.2 如何使用特殊方法-通过创建一个向量类的例子
- 1.3 特殊方法汇总
第一章 Python 数据模型
python最好的品质是一致性
python解释器碰到特殊句法时,会使用特殊方法去激活一些基本的对象操作
这些特殊的方法以两个下划线开头,以两个下划线结尾,如__getitem__、__len__等
所谓的特殊句法,如通过下标访问列表,获取自定义类的元素的个数、重构操作符等等
__getitem__的读法: dunder getitem
随着学习的推进,对这一点的理解会逐渐加深......
我认为 ,特殊方法的实现,就是运算符的重构......
本章通过两个例子,来说明特殊用法
- 纸牌的例子
- 向量的例子
注:特殊方法是为了让编译器调用的,自己不需要调用。如没有obj.__len__()这种写法,应该使用len(obj)。此外, 不要自己想当然地随意添加特殊方法。
1.1 python风格的纸牌
创建一个纸牌类,实现
__getitem__和__len__两个特殊方法
代码如下
import collections
Card = collections.namedtuple('Card', ['rank', 'suit']) # 可以用来创建只有少数属性没有方法的类class FrenchDeck:ranks = [str(n) for n in range(2, 11)] + list('JQKA') # 创建一个list 存放2-Asuits = 'spades diamonds clubs hearts'.split() # 花色: 黑桃、红桃、方块、梅花# split默认为所有的空字符,包括空格、换行(\n)、制表符(\t)等。def __init__(self):self._cards = [Card(rank, suit)for suit in self.suitsfor rank in self.ranks]def __len__(self):return len(self._cards)def __getitem__(self, position):return self._cards[position]
创建一个纸牌类之后,对上述类可以进行操作,代码如下:
def run_card():# 打印输出通过collections.namedtuple创建的类、以及类型test_card = Card('7', 'diamonds') print(test_card)print(type(test_card))deck = FrenchDeck()print(deck.ranks)print(deck.suits)print(len(deck)) # 获取FrenchDeck类中元素的个数 调用__len__print(deck[8]) # 根据下标获取FrenchDeck类中的元素 调用__getitem__# 通过python 内置的方法进行随机选择,而不必重新写一个对象from random import choiceprint(choice(deck)) # 随机从类中选择一个元素print(choice(deck))# 可以使用自动切片,因为__getitem__方法把[]操作给了self._cards,所以可以使用切片print(deck[:3]) # 下标为0、1、2print(deck[12::13]) # 抽出索引是12的牌, 步长为13,一次取1个# 可迭代,因为有__getitem__,可以进行迭代、逆迭代for card in deck:print(card)# 反向迭代for card in reversed(deck):print(card)# 由于是可迭代的,因此可以使用 in, # 集合类型没有实现__contains__方法,那么in运算符就会按顺序进行一次迭代搜索。print(Card('Q', 'hearts') in deck)print(Card('r', 'hearts') in deck)# 排序 因为可以迭代,因此可以进行排序for card in sorted(deck, key=spades_high): # spades_high为排序策略的方法名print(card)suit_values = dict(spades=3, hearts=2, diamonds=1, clubs=0) # 花色的大小定义
def spades_high(card):rank_value = FrenchDeck.ranks.index(card.rank) # 元素在类中的下标# print(card.rank +';'+ card.suit)# print('rank_value:'+str(rank_value))# print('len:'+ str(len(suit_values)))# print('*=' + str(rank_value * len(suit_values)))return rank_value * len(suit_values) + suit_values[card.suit]
FrenchDeck类隐式继承了Object类,但是功能却不是继承而来的
我们通过数据模型和一些合成来实现这些功能
通过实现__len__和__getitem__这两个特殊方法,FrenchDeck类就与python自有的序列数据类型一样,可以体现出python的核心语言特性
FrenchDeck类还可以用于标准库中random.choice、reversed、sorted这些函数
对合成的运用可以使得__len__、__getitem__的具体实现可以代理给self._cards这个列表
1.2 如何使用特殊方法-通过创建一个向量类的例子
实现一个二维向量类
Vector。
当然向量相关的运算在类中要进行实现,如输出(+)、取模(abs)、向量与数的乘法(*)、布尔判断(bool)
输出:通过内置函数
repr,可以把一个对象用字符串形式表示出来以便辨认,这就是"字符串表示形式"
repr是通过特殊方法__repr__来实现的,
如果没有实现这个特殊方法,<Vector object at 0x10e100070>
如果使用%来表示字符串,repr是通过%r来表示的
如果使用!来表示字符串,repr是通过!r来表示的
__repr__所返回的字符串应该准确、无歧义,并且尽可能表达出如何用代码创建出这个被打印的对象
__repr__和__str___的区别在于:后者是在str()被使用或者用print()打印一个对象时才被调用
由于python在调用str()时,如果没有发现__str__就会调用__repr__,因此优先创建__repr__
加法(
+):Vector(2, 3) + Vectotr(3, 5) = Vector(5, 8)
采用特殊方法__add__:这个特殊方法返回的是一个新的对象,被操作的两个对象原封不动。
向量与数的相乘(
*):Vector(2, 3) * 2 = Vector(4, 6)、Vector(4, 6) * (-2) = Vector(-8, -12)
采用特殊方法__mul__:这个特殊方法同__add__一样,都是返回一个新的对象。
取模运算(
abs):所谓的取模:就是元素的平方和再开方,即二范数 或 欧几里得范数
采用特殊方法__abs__
abs是一个内置函数,如果输入是整数或者浮点数,返回的是其绝对值;如果输入的是一个复数。返回的是复数的模
因此在Vector这个类中,通过调用abs,应当返回的是向量的模。
布尔运算(bool):这个函数只能返回
True、False
默认情况下,我们自己定义的类的实例总被认为是真的,除非这个类对__bool__或__len__有自己的实现,
bool(x)是调用x.__bool__()的结果,如果不存在__bool__,会调用__len__,如果返回0,bool就返回False,否则,返回True
Vector类的实现如下:
from math import hypot # hypot 是用来求欧几里得范数的class Vector:def __init__(self, x=0, y=0): # 定义了 x y 应该是整数类型self.x = xself.y = ydef __repr__(self): # __repr__ 中要使用 %r 保存原格式 %r可以用来获取对象各个属性的标准字符串表示形式return 'Vector(%r, %r)' % (self.x, self.y) # 此时输出的应该为 Vector(3, 4)def __abs__(self):return hypot(self.x, self.y) # 返回欧几里得范数 就是向量的模# 如果模是0 返回False 否则返回True# 法1# def __bool__(self):# return bool(abs(self))# 法2 更高效,省掉了abs到__abs__到平方再到平方根这些过程def __bool__(self):return bool(self.x or self.y) # or运算可能返回x或y本身的值,若x的值为真,则or返回x的值,否返回y的值def __add__(self, other):x = self.x + other.xy = self.y + other.yreturn Vector(x, y)def __mul__(self, scalar):return Vector(self.x * scalar, self.y * scalar)
对
Vector类的功能的调用,代码如下:
def run_vector():vector1 = Vector(3, 4)print('向量1=%r' % vector1)print('向量的模长= %f' % abs(vector1))vector2 = Vector(1, 2)print('向量2 = %r' % vector2)print('向量1 + 向量2 = %r' % (vector1 + vector2))# print('向量1 * 3 = %r' % (vector1 * 3)) # 数在后,向量在前,与__mul__一致print('向量1的bool = %r' % bool(vector1))
1.3 特殊方法汇总
python语法参考手册中的 Data Model列出了83个特殊方法的名字。下面列出概况。
下表的分类方式与官方文档不同
与运算符无关的特殊方法:
| 类别 | 方法名 |
|---|---|
| 字符串/字节序列表示形式 | __repr__、 __str__、 __format__、 __bytes__ |
| 数值转换 | __abs__、 __bool__、 __complex__、 __int__、 __float__、 __hash__、 __index__ |
| 集合模拟 | __len__、 __getitem_、 __seitem__、 __delitem__、 __contains__ |
| 迭代枚举 | __iter__、 __reversed__、 __next__ |
| 可调用模拟 | __call__ |
| 上下文管理 | __repr__、 __repr__ |
| 实例创建和销毁 | __new__、 __init__、 __del__ |
| 属性管理 | __getattr__、 __getattribute__、 __setattr__、 __delattr__、 __dir__ |
| 属性描述符 | __get__、 __set__、 __delete__ |
| 跟类相关的服务 | __prepare__、 __instancecheck__、 __subclasscheck__ |
跟运算法相关的特殊方法
| 类别 | 方法名 |
|---|---|
| 一元运算符 | __neg__ -、 __pos__ +、 __abs__ abs()、 |
| 比较运算符 | __lt__ <、 __le__ <=、 __eq__ ==、 __ne__ !=、 __gt__ >、 __ge__ >=、 |
| 算术运算符 | __add__ +、__sub__ -、 __mul__ *、__truediv__ /、 __floordiv__ //、 __mod__ %、 __divmod__ divmod()、__pow__ ** 或pow()、 __round__ round() |
| 反向算术运算符 | __radd__、 __rsub__、 __rmul__、 __rtruediv__、 __rfloordiv__、 __rmod__、 __rdivmod__ |
| 增量赋值算术运算符 | __iadd__、 __isub__、 __imul__、 __itruediv__、 __ifloordiv__、__imod__、 __ipow__ |
| 位运算符 | __invert__ ~、 __lshift__ <<、 __rshift__>>、 __and__ &、 __or__ |
| 反向位运算符 | __rlshift__、 __rrshift__、 __rand__、 __rxor__、 __ror__ |
| 增量赋值位运算符 | __ilshift__、 __irshift__、 __iand__、 __ixor__、 __ior__ |
增量赋值运算符:
a *= b
反向算术运算符,当两个操作数交换了前后位置,此时想要得到一致的结果,需要调用反向算术运算符
相关文章:
【流畅的python】第一章 Python数据模型
文章目录第一章 Python 数据模型1.1 python风格的纸牌1.2 如何使用特殊方法-通过创建一个向量类的例子1.3 特殊方法汇总第一章 Python 数据模型 python最好的品质是一致性 python解释器碰到特殊句法时,会使用特殊方法去激活一些基本的对象操作 这些特殊的方法以两个…...
from文件突然全部变为类cs右击无法显示设计界面
右击也不显示查看设计器 工程文件 .csproj中将 <Compile Include"OperatorWindows\Connection.cs" /> <Compile Include"OperatorWindows\Connection.Designer.cs"> <DependentUpon>Connection.cs</DependentUpon> &…...
使用arthas中vmtool命令查看spring容器中对象的某个属性
场景: 线上环境我想查看spring中容器某个对象的属性值 vmtool命令 方式一: vmtool --action getInstances -c [类加载器的hash] --className [目标类全路径] --limit 10 -x 2 实例:查询该类的全部属性情况(该类是一个spri…...
四种幂等性解决方案
什么是幂等性? 幂等是一个数学与计算机学概念,在数学中某一元运算为幂等时,其作用在任一元素两次后会和其作用一次的结果相同。 在计算机中编程中,一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同。 幂等…...
【Nacos】Nacos配置中心客户端配置更新源码分析
上文我们说了服务启动的时候从远程Nacos服务端拉取配置,这节我们来说下Nacos服务端配置的变动怎么实时通知到客户端,首先需要注册监听器。 注册监听器 NacosContextRefresher类会监听应用启动发布的ApplicationReadyEvent事件,然后进行配置…...
按钮防抖与节流-vue2
防抖与节流,应用场景有很多,例如:禁止重复提交数据的场景、搜索框输入搜索条件,待输入停止后再开始搜索。 防抖 点击button按钮,设置定时器,在规定的时间内再次点击会重置定时器重新计时,在规定…...
PyTorch学习笔记:nn.SmoothL1Loss——平滑L1损失
PyTorch学习笔记:nn.SmoothL1Loss——平滑L1损失 torch.nn.SmoothL1Loss(size_averageNone, reduceNone, reductionmean, beta1.0)功能:创建一个平滑后的L1L_1L1损失函数,即Smooth L1: l(x,y)L{l1,…,lN}Tl(x,y)L\{l_1,\dots,l…...
2年时间,涨薪20k,想拿高薪还真不能老老实实的工作...
2016年开始了我的测试生活。 2016年刚到公司的时候,我做的是测试工程师。做测试工程师是我对自己的职业规划。说实话,我能得到这份工作真的很高兴。 来公司的第一个星期,因为有一个项目缺人,所以部门经理提前结束了我的考核期&a…...
Spark - Spark SQL中RBO, CBO与AQE简单介绍
Spark SQL核心是Catalyst, Catalyst执行流程主要分4个阶段, 语句解析, 逻辑计划与优化, 物理计划与优化, 代码生成 前三个阶段都由Catalyst负责, 其中, 逻辑计划的优化采用RBO思路, 物理计划的优化采用CBO思路 RBO (Rule Based Optimization) 基于规则优化, 通过一系列预定好…...
NeurIPS/ICLR/ICML AI三大会国内高校和企业近年中稿量完整统计
点击文末公众号卡片,找对地方,轻松参会。 近日,有群友转发了一张网图,统计了近年来中国所有单位在NeurIPS、ICLR、ICML论文情况。原图如下: 中稿数100: 清华(1) 北大(2) 占比:22.6%。 累计数…...
Android IO 框架 Okio 的实现原理,到底哪里 OK?
本文已收录到 AndroidFamily,技术和职场问题,请关注公众号 [彭旭锐] 提问。 前言 大家好,我是小彭。 今天,我们来讨论一个 Square 开源的 I/O 框架 Okio,我们最开始接触到 Okio 框架还是源于 Square 家的 OkHttp 网络…...
一文讲解Linux 设备模型 kobject,kset
设备驱动模型 面试的时候,有面试官会问,什么是Linux 设备驱动模型?你要怎么回答? 这个问题,突然这么一问,可能你会愣住不知道怎么回答,因为Linux 设备驱动模型是一个比较整体的概念࿰…...
linux配置密码过期的安全策略(/etc/login.defs的解读)
长期不更换密码很容易导致密码被破解,而linux的密码过期安全策略主要在/etc/login.defs中配置。一、/etc/login.defs文件的参数解读1、/etc/login.defs文件的内容示例[rootlocalhost ~]# cat /etc/login.defs # # Please note that the parameters in this configur…...
c_character_string 字符串----我认真的弄明白了,也希望你们也是。
字符串 1. 字符串长度strlen 1.1strlen 函数介绍 size_t strlen ( const char * str );strlen ——string length strlen 的头文件是 #include <string.h> 参数指向的字符串必须要以 ‘\0’ 结束。 strlen 是求字符串长度的函数,统计的是字符串中\0之前出现…...
spring面试题 一
一、为了降低Java开发的复杂性,Spring采取了那4种关键策略 基于POJO的轻量级和最小侵入性编程; 通过依赖注入和面向接口实现松耦合; 基于切面和惯例进行声明式编程; 通过切面和模板减少样板式代码。 二、Spring框架的核心&am…...
C++中char *,char a[ ]的特殊应用
1.数组的本质 数组是多个元素的集合,在内存中分布在地址相连的单元中,所以可以通过其下标访问不同单元的元素。 2.指针 指针也是一种变量,只不过它的内存单元中保存的是一个标识其他位置的地址。 3.字符串常量的本质是它的第一个字符的地…...
【Windows10】电脑副屏无法调节屏幕亮度?解决方法
先说下情况,本人对显示器不太懂,属于小白 这个副屏无法调节的问题出现也已经很久了,但是之前亮度适合就无所谓,今天突然按了之后很亮,于是就找问题。 第一步,我直接百度,遇事不决,百…...
Paper简读 - ProGen2: Exploring the Boundaries of Protein Language Models
欢迎关注我的CSDN:https://spike.blog.csdn.net/ 本文地址:https://blog.csdn.net/caroline_wendy/article/details/128976102 ProGen2: Exploring the Boundaries of Protein Language Models ProGen2:探索蛋白质语言模型的边界Cumulative density:累积密度 Ligand:在生…...
leaflet 加载WKT数据(示例代码050)
第050个 点击查看专栏目录 本示例的目的是介绍演示如何在vue+leaflet中加载WKT文件,将图形显示在地图上。 直接复制下面的 vue+openlayers源代码,操作2分钟即可运行实现效果; 注意如果OpenStreetMap无法加载,请加载其他来练习 文章目录 示例效果配置方式示例源代码(共67行…...
设计模式-组合模式和建筑者模式详解
一. 组合模式 1. 背景 在现实生活中,存在很多“部分-整体”的关系,例如,大学中的部门与学院、总公司中的部门与分公司、学习用品中的书与书包、生活用品中的衣月艮与衣柜以及厨房中的锅碗瓢盆等。在软件开发中也是这样,例如&…...
利用最小二乘法找圆心和半径
#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...
深入浅出Asp.Net Core MVC应用开发系列-AspNetCore中的日志记录
ASP.NET Core 是一个跨平台的开源框架,用于在 Windows、macOS 或 Linux 上生成基于云的新式 Web 应用。 ASP.NET Core 中的日志记录 .NET 通过 ILogger API 支持高性能结构化日志记录,以帮助监视应用程序行为和诊断问题。 可以通过配置不同的记录提供程…...
【算法训练营Day07】字符串part1
文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接:344. 反转字符串 双指针法,两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...
【单片机期末】单片机系统设计
主要内容:系统状态机,系统时基,系统需求分析,系统构建,系统状态流图 一、题目要求 二、绘制系统状态流图 题目:根据上述描述绘制系统状态流图,注明状态转移条件及方向。 三、利用定时器产生时…...
自然语言处理——Transformer
自然语言处理——Transformer 自注意力机制多头注意力机制Transformer 虽然循环神经网络可以对具有序列特性的数据非常有效,它能挖掘数据中的时序信息以及语义信息,但是它有一个很大的缺陷——很难并行化。 我们可以考虑用CNN来替代RNN,但是…...
Typeerror: cannot read properties of undefined (reading ‘XXX‘)
最近需要在离线机器上运行软件,所以得把软件用docker打包起来,大部分功能都没问题,出了一个奇怪的事情。同样的代码,在本机上用vscode可以运行起来,但是打包之后在docker里出现了问题。使用的是dialog组件,…...
破解路内监管盲区:免布线低位视频桩重塑停车管理新标准
城市路内停车管理常因行道树遮挡、高位设备盲区等问题,导致车牌识别率低、逃费率高,传统模式在复杂路段束手无策。免布线低位视频桩凭借超低视角部署与智能算法,正成为破局关键。该设备安装于车位侧方0.5-0.7米高度,直接规避树枝遮…...
【SpringBoot自动化部署】
SpringBoot自动化部署方法 使用Jenkins进行持续集成与部署 Jenkins是最常用的自动化部署工具之一,能够实现代码拉取、构建、测试和部署的全流程自动化。 配置Jenkins任务时,需要添加Git仓库地址和凭证,设置构建触发器(如GitHub…...
LCTF液晶可调谐滤波器在多光谱相机捕捉无人机目标检测中的作用
中达瑞和自2005年成立以来,一直在光谱成像领域深度钻研和发展,始终致力于研发高性能、高可靠性的光谱成像相机,为科研院校提供更优的产品和服务。在《低空背景下无人机目标的光谱特征研究及目标检测应用》这篇论文中提到中达瑞和 LCTF 作为多…...
【把数组变成一棵树】有序数组秒变平衡BST,原来可以这么优雅!
【把数组变成一棵树】有序数组秒变平衡BST,原来可以这么优雅! 🌱 前言:一棵树的浪漫,从数组开始说起 程序员的世界里,数组是最常见的基本结构之一,几乎每种语言、每种算法都少不了它。可你有没有想过,一组看似“线性排列”的有序数组,竟然可以**“长”成一棵平衡的二…...
