python类的特殊方法汇总_Python笔记001-类的特殊方法

Python笔记001-类的特殊方法

以下是我学习《流畅的Python》后的个人笔记,现在拿出来和大家共享,希望能帮到各位Python学习者。

首次发表于: 微信公众号:科技老丁哥,ID: TechDing,敬请关注。

本篇主要知识点:

类的特殊方法(一般都在前后带有两个下划线,比如__len__和__getitem__),其存在的目的是被Python解释器调用,而不是类的对象来调用。

对于自定义的类,一般无法体现出Python语言的核心特性,比如迭代和切片等,但是可以通过在自定义类中复写__len__和__getitem__等特殊方法来实现这些核心功能。对象调用len()方法时实际上Python解释器调用的是自定义类中的__len__,而对某个对象进行切片获取元素,或者排序时,Python解释器调用的是复写的__getitem__。

在自定义类中复写__getitem__至少可以获得1.类对象的切片和获取元素,2.对类对象进行迭代,可以是顺序迭代也可以是逆序迭代,3.对类对象进行重新排序,4.对类对象进行随机抽样等多种功能。

类的特殊方法有多达100种,作为示例,此处仅仅总结了加减乘除等的复写方法,并将所有特殊方法都整理成相关表格,便于后续复写某些特殊方法时作为参考。

1. 特殊方法示例

这些特殊方法长得比较奇怪,那是因为它提醒用户,不要轻易调用这些方法,因为它基本上是Python解释器专用。

比如下面先建立一整副纸牌,它包含有一个属性_cards,这个一个list,包含有52个Card对象。在复写了__len__和__getitem__方法之后,就可以直接获取到这个_cards属性的总长度和对其进行排序,切片来获取某几张纸牌。

from collections import namedtuple

Card=namedtuple('Card', ['rank', 'suit']) # 单张纸牌类

class FrenchDeck: # 一副纸牌,包含4种花色,每种13种数字

ranks = [str(n) for n in range(2, 11)] + list('JQKA') # 13种数字

suits = 'spades diamonds clubs hearts'.split() # 四种不同花色:黑桃,方块,梅花,红桃

def __init__(self):

self._cards = [Card(rank, suit) for suit in self.suits

for rank in self.ranks]

# _cards属性是所有纸牌的集合,一个list, 包含4种花色共52张牌

def __len__(self):

# 类FrechDeck的特殊方法:会计算所有纸牌的张数,即52

return len(self._cards)

def __getitem__(self, position):

# 类FrechDeck的特殊方法:从52张牌获取第position张牌

return self._cards[position]

构建一副纸牌后,我们想知道里面有多少张牌,或者想知道第1张,第10张,最后一张纸牌分别是什么:

## 通过len()获取deck中一共有多少张牌

deck=FrenchDeck()

print(len(deck)) # 52

## 通过切片方法获取某个位置的牌

print(deck[0]) # Card(rank='2', suit='spades')

print(deck[10]) # Card(rank='Q', suit='spades')

print(deck[-1]) # Card(rank='A', suit='hearts')

如果没有复写__len__函数,在len(deck)时会报错:TypeError: object of type 'FrenchDeck' has no len().

同理,如果没有复写__getitem__方法,在deck[0]时报错:TypeError: 'FrenchDeck' object does not support indexing

可以对deck进行索引来获取某一个位置的纸牌,那么也就可以通过切片来获取一个批次,符合一定条件的纸牌,比如下面获取最后三张牌和牌面全是A的牌。

print(deck[-3:]) # 获取最后三张牌

print(deck[12::13]) # 获取全是A的牌,间隔型切片

同理,复写了__getitem__方法后,就可以对deck对象进行迭代,不管是顺序迭代还是逆序迭代都可以。

# 顺序迭代

for card in deck[:10]: # 只打印最前面的10张牌

print(card)

# 逆序迭代

for card in reversed(deck[-10:]): # 只打印最后面的10张牌

print(card)

还可以判断某张牌是否存在于该副牌内:

## 判断某张牌是否存在于该副牌内:

print(Card('Q', 'hearts') in deck) # True

print(Card('Z', 'clubs') in deck) # False

有了__getitem__方法,就可以对所有纸牌进行排序操作,此处我们排序的规定是:梅花2最小,方块2次之,红桃2,黑桃2,梅花3.。。这种形式,所以要自定义一个排序方法,这个方法返回一个整数,代表每张牌的大小,那么最小的梅花2就是0,最大的黑桃A就是51。

## 使用自定义方法对所有纸牌进行重新排序

suit_values = dict(spades=3, hearts=2, diamonds=1, clubs=0) # 将花色转换为数值

def spades_high(card):

rank_value = FrenchDeck.ranks.index(card.rank) # 获取某张牌的数字

return rank_value * len(suit_values) + suit_values[card.suit]

# 将某张牌的数字和花色换成整数返回

for card in sorted(deck, key=spades_high):

# 按照自定义方法spades_high得到的整数进行排序

print(card)

小结一下:自定义类通过复写__getitem__方法,可以获得多种原来不存在的功能:比如切片功能,索引功能,还可以判断某个对象是否存在于类对象列表中,还可以对类对象进行迭代操作和排序操作。

2. 特殊方法的使用

对于自定义的类型,使用这些特殊方法可以使得他们的表现具有某些Python核心功能,在你对这些自定义类型进行操作时,比如len(deck)时,Python解释器会去找deck类的__len__方法。

而Python内置的类型,比如list, str, tuple等,Python解释器则直接抄近路,会直接返回PyVarObject里的Ob_size属性,这是一个长度可变的C语言结构体,所以速度要比调用__len__方法快得多。

你自己对这些特殊方法的使用频率会很低,因为都是Python解释器自动调用,只有类定义时的__init__方法例外。

2.1 自定义加减乘除功能

class Person:

def __init__(self,name,age,score):

self.name=name

self.age=age

self.score=score

def __add__(self,other):

# 此处仅仅是将得分相加

return self.score+other.score

def __sub__(self,other):

# 此处将得分相减

return self.score-other.score

def __mul__(self,other):

# 此处将两个的年龄相乘

return self.age*other.age

def __truediv__(self,other):

# 将两个的得分相除

return self.score/other.score

这个自定义类Person复写了加减乘除方法,根据需要对里面的属性进行算术操作,那么就可以用符号+,-,*,/等进行操作,比如:

P1=Person('Jack',20,90)

P2=Person('Rose',18,60)

print(P1+P2) # 150

print(P1-P2) # 30

print(P1*P2) # 360

print(P1/P2) # 1.5

2.2 自定义print后的形式

还有一个非常常用的特殊函数:__repr__,它决定了print被直接调用后结果表现形式。

class Person:

def __init__(self,name,age,score):

self.name=name

self.age=age

self.score=score

def __repr__(self):

return 'Person(name={},age={},score={})'.format(self.name,self.age,self.score)

P1=Person('Jack',20,90)

print(P1) # Person(name=Jack,age=20,score=90)

如果没有复写__repr__,在用print(P1)时,会得到内存地址信息,人眼无法判断出具体内容,复写之后,就可以按照我们想要的形式直接print。

3. 特殊方法汇总

Python内置的特殊方法有将近一百种,其中有很多是实现算数运算,位运算和比较操作的,下面将这些方法的意义总结如下:

所以,如果自定义类想实现某方面的功能,可以参考上面的表格来逐一实现即可。

首次发表于: 微信公众号:科技老丁哥,ID: TechDing,敬请关注。

本文所有代码都已经上传到我的github,欢迎下载

参考资料:

《流畅的Python》,Luciano Ramalho (作者) 安道 , 吴珂 (译者)。

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

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

相关文章

什么是联邦学习

联邦学习 1.1 联邦学习的概念 历史:联邦学习最早在 2016 年由谷歌提出,原本用于解决安卓手机终端用户在本地更新模型的问题; 本质:联邦学习本质上是一种分布式机器学习技术,或机器学习框架。 目标:联邦学…

循环自增_大学C语言—循环结构及应用

基础知识常见循环结构及形式for循环for(设置初始值;循环条件判断;设置循环增减量){语句1;语句2;…… 语句n;}while循环while(条件判断){语句1;语句2;……语句n;}do-while循环d…

论文写作的辅助工具

1 英文翻译 translate.google.cn 2 英文句子 我们以前的做法是要求每个同学收集一些经典的句子,现在有一个网站已经把这个工作做好了,这个可以解决60%句子问题,接下来就是写作的逻辑 https://www.phrasebank.manchester.ac.uk/ 3 画图工具…

dac0832控制电机驱动流程图_某驱动电机控制器拆解实拍照片

小编作为一个电控专业100%小白,机缘巧合获得某纯电动汽车驱动电机控制器一台,拆解之,权为业内人士参考之用,文中显得外行、用词不对及谬误之处还请各位大神不吝赐教!外观标牌背面拆解固定托架侧面拆解固定托架拆解固定…

推荐系统--安全联邦矩阵分解(7)

相关论文: Secure Federated Matrix Factorization 论文源代码见: https://github.com/Di-Chai/FedMF 1 摘要 为了保护用户隐私和满足法律法规,联邦(机器)学习近年来获得了广泛的关注。 联邦学习的关键原则是在不需要知道每个用…

联邦学习--数据攻击(1)

参考论文:Deep Leakage from Gradients(NeurIPS 2019) 源代码: https://github.com/mit-han-lab/dlg 核心思想:作者通过实验得到,从梯度可以反推用户的个人信息。并验证了其在计算机视觉和自然语言处理任务…

python制作图_Python做图的方法

最近一直没有更新文章,在学习Machine learning。然后业余在kaggle那里瞎转,对Python常用的作图摸了个遍,本文将对这些作图方法做个简单介绍一般我们作图主要是为了看数据分布、数据趋势、以及比较大小。常用的图包括:line(折线图)…

联邦学习--数据攻击(2)

参考论文:See through Gradients: Image Batch Recovery via GradInversion(CVPR 2021 ) 源代码: 核心思想:解决了Deep Leakage from Gradients(NeurIPS 2019)中batch大于1效果无效的情况。 缺点…

python简单网络爬虫_【Python】 简单网络爬虫实现

介绍网络爬虫(英语:网络爬虫),也称为网络蜘蛛(蜘蛛)是一个Web机器人用于自动浏览万维网。其目的通常是为了编译web索引。\u2014\u2014维基百科web爬虫程序可以节省他们访问的页面,以便搜索引擎可以为用户搜索生成索引。一般来说,有两个步骤:1。获取网页内容2。准备获得web内容和…

对抗攻击(1)

本文是根据李宏毅老师在B站上的视频整理而来,视频地址为: https://www.bilibili.com/video/BV1n3411y7xD?p65 1 无目标和有目标攻击的区别 无目标攻击:攻击后的标签不确定,只要是和原始标签差别越大越好。 有目标攻击&#xff…

python爬虫隐藏ip_Python3网络爬虫之使用User Agent和代理IP隐藏身份

本文介绍了Python3网络爬虫之使用User Agent和代理IP隐藏身份,分享给大家,具体如下:运行平台:WindowsPython版本:Python3.xIDE:Sublime text3一、为何要设置User Agent有一些网站不喜欢被爬虫程序访问&…

对抗攻击(2)

本文将介绍一些经典的对抗攻击算法,未完待续…

乌班图快速创建ftp

需求:乌班图22.04安装配置ftp,然后配置一个用户,用户名deviceftp密码aaaa,并且设置端口为60021,并且限制在/app/deviceftp目录下,不允许匿名登录 在Ubuntu 22.04上安装和配置FTP服务器的步骤如下&#xff…

自注意力机制Self-attention(1)

目录: 自注意力机制Self-attention(1) 自注意力机制Self-attention(2) 本文是对李宏毅老师的课程进行了整理。 视频地址为: https://www.bilibili.com/video/BV1Wv411h7kN?p23 1 问题引入 问&#xff1a…

id门禁卡复制到手机_手机NFC有哪些功能?怎么设置手机门禁卡?别浪费了手机的NFC功能...

NFC功能早前都运用一些手机旗舰机中,随着手机技术的发展,现在有许多的手机都有NFC的功能,那手机中的NFC只是个摆设吗?NFC不仅仅有不依靠数据网络、安全稳定的特点,其实还有许多你不知道的功能!比如可以用来…

自注意力机制Self-attention(2)

目录: 自注意力机制Self-attention(1) 自注意力机制Self-attention(2) 1 内容回顾 以b2b^2b2的计算过程为例来说明: query: q1Wqa1q^1 W^q a^1q1Wqa1, q2Wqa2q^2 W^q a^2q2Wqa2, q3Wqa3q^3 …

python 打印xml文档树_Python构建XML树结构的方法示例

本文实例讲述了Python构建XML树结构的方法。分享给大家供大家参考,具体如下:1.构建XML元素#encodingutf-8from xml.etree import ElementTree as ETimport sysrootET.Element(color) #用Element类构建标签root.text(black) #设置元素内容treeET.ElementT…

风格迁移模型测试效果

1 模型简介 Selfie2anime模型:动漫风格,训练集主要针对人物头像;对应论文为:U-gat-it: Unsupervised generative attentional networks with adaptive layer-instance normalization for image-to-image translation Hayao模型&a…

黑白棋级别预测

1 当前成果 上图是对于AI级别为40级以下的对局结果统计图,横坐标是对于AI级与当前模型预测级别的差值,纵坐标是玩家的胜率。由图中可以看出,玩家胜率符合预测。当AI级别比预测级别高时,玩家胜率越来越低,反之玩家胜率会…

python3源代码是什么_如何用inspect查找python3源代码?

我们在学习的时候喜欢去写代码,或者进行代码的测试,在源代码的查看的进行的不多。大概很多是写完就放在一边,如果不是下次需要使用,也不会知道写的是否正确,还有没有可以修改或者改进的地方。所以,对于源代…