当前位置:首页 > 数码 > Python-每个程序员都应该知道的-个-魔术方法-11 (python怎样打开)

Python-每个程序员都应该知道的-个-魔术方法-11 (python怎样打开)

admin8个月前 (04-15)数码79

译者|布加迪

审校|重楼

在/target=_blankclass=infotextkey>Python中,魔术方法(MagicMethod)可以协助您模拟Python类中内置函数的行为。这些方法有前后双下划线(__),因此也被称为Dunder方法。

这些魔术方法还可以协助您在Python中成功操作符重载。您或者见过这样的例子,就像两个整数与乘法运算符*一同经常使用失掉乘积一样。当它与字符串和整数k一同经常使用时,字符串会重复k次:

>>>3*412>>>'code'*3'codecodecode'

咱们在本文中将经过创立一个便捷的二维向量Vector2D类来探求Python中的魔术方法。

咱们将从您或者相熟的方法入手,逐渐构建更有协助的魔术方法。

无妨开局编写一些魔术方法!

1.__init__

思考上方的Vector2D类:

classVector2D:pass

一旦您创立了类,并实例化对象,就可以减少如下属性:obj_name.attribute_name=value。

但是,您须要在实例化对象时初始化这些属性,而不是手意向创立的每个实例减少属性(当然,这一点也不幽默!)。

为此,您可以定义__init__方法。无妨为Vector2D类定义__init__方法:

classVector2D:def__init__(self,x,y):self.x=xself.y=yv=Vector2D(3,5)

2.__repr__

当您尝试审核或打印输入实例化的对象时,您将发现没有失掉任何有协助的消息。

v=Vector2D(3,5)print(v)Output>>><__mn__.Vector2Dobjectat0x7d2fcfaf0ac0>

这就是为什么您应该减少一个示意字符串,一个对象的字符串示意。为此,减少__repr__方法,如下所示:

classVector2D:def__init__(self,x,y):self.x=xself.y=ydef__repr__(self):returnf"Vector2D(x={self.x},y={self.y})"v=Vector2D(3,5)print(v)Output>>>Vector2D(x=3,y=5)

__repr__应该蕴含创立类实例所需的一切属性和消息。__repr__方法通罕用于调试目标。

__str__也用于减少对象的字符串示意。通常,__str__方法用于为类的最终用户提供消息。

无妨给咱们的类减少一个__str__方法:

classVector2D:def__init__(self,x,y):self.x=xself.y=ydef__str__(self):returnf"Vector2D(x={self.x},y={self.y})"v=Vector2D(3,5)print(v)Output>>>Vector2D(x=3,y=5)

假设没有__str__的成功,它就前往到__repr__。因此关于您创立的每个类,您至少应该减少__repr__方法。

接上去,无妨减少一个方法来审核Vector2D类的恣意两个对象能否相等。假设两个向量有相反的x和y坐标,它们是相等的。

如今创立两个具备相等x和y值的Vector2D对象,并比拟它们能否相等:

v1=Vector2D(3,5)v2=Vector2D(3,5)print(v1==v2)

结果为False,由于自动状况下比拟会审核内存中对象ID能否相等。

Output>>>False

无妨减少__eq__方法来审核能否相等:

classVector2D:def__init__(self,x,y):self.x=xself.y=ydef__repr__(self):returnf"Vector2D(x={self.x},y={self.y})"def__eq__(self,other):returnself.x==other.xandself.y==other.y

审核相等性如今应该按预期上班:

v1=Vector2D(3,5)v2=Vector2D(3,5)print(v1==v2)Output>>>True

Python的内置len()函数可以协助您计算内置可迭代对象(iterable)的长度。比如说,就向量而言,length应该前往该向量所蕴含的元素的个数。

所以无妨为Vector2D类减少一个__len__方法:

classVector2D:def__init__(self,x,y):self.x=xself.y=ydef__repr__(self):returnf"Vector2D(x={self.x},y={self.y})"def__len__(self):return2v=Vector2D(3,5)print(len(v))

Vector2D类的一切对象长度为2:

Output>>>2

如今无妨思考对向量口头的经常出现运算。无妨减少魔术方法来加减恣意两个向量。

假设您间接尝试减少两个向量对象,就会遇到失误。所以您应该减少一个__add__方法:

classVector2D:def__init__(self,x,y):self.x=xself.y=ydef__repr__(self):returnf"Vector2D(x={self.x},y={self.y})"def__add__(self,other):returnVector2D(self.x+other.x,self.y+other.y)

您如今可以像这样减少恣意两个向量:

v1=Vector2D(3,5)v2=Vector2D(1,2)result=v1+v2print(result)Output>>>Vector2D(x=4,y=7)

接上去,无妨减少一个__sub__方法来计算Vector2D类的恣意两个对象之间的差异:

classVector2D:def__init__(self,x,y):self.x=xself.y=ydef__repr__(self):returnf"Vector2D(x={self.x},y={self.y})"def__sub__(self,other):returnVector2D(self.x-other.x,self.y-other.y)v1=Vector2D(3,5)v2=Vector2D(1,2)result=v1-v2print(result)Output>>>Vector2D(x=2,y=3)

咱们还可以定义__mul__方法来定义对象之间的乘法。

无妨来处置:

classVector2D:def__init__(self,x,y):self.x=xself.y=ydef__repr__(self):returnf"Vector2D(x={self.x},y={self.y})"def__mul__(self,other):#Scalarmultiplicationifisinstance(other,(int,float)):returnVector2D(self.x*other,self.y*other)#Dotproductelifisinstance(other,Vector2D):returnself.x*other.x+self.y*other.yelse:raiseTypeError("Unsupportedoperandtypefor*")

如今咱们将举几个例子,看看__mul__方法是如何实践上班的。

v1=Vector2D(3,5)v2=Vector2D(1,2)#Scalarmultiplicationresult1=v1*2print(result1)#Dotproductresult2=v1*v2print(result2)Output>>>Vector2D(x=6,y=10)13

9.__getitem__

__getitem__魔术方法让您可以索引对象,并经常使用相熟的方括号[]语法访问属性或属性切片。

Python

关于Vector2D类的对象v:

假设您尝试经过索引访问,您会遇到失误:

v=Vector2D(3,5)print(v[0],v[1])---------------------------------------------------------------------------TypeErrorTraceback(mostrecentcalllast)in()---->1print(v[0],v[1])TypeError:'Vector2D'objectisnotsubscriptable

无妨成功__getitem__方法:

classVector2D:def__init__(self,x,y):self.x=xself.y=ydef__repr__(self):returnf"Vector2D(x={self.x},y={self.y})"def__getitem__(self,key):ifkey==0:returnself.xelifkey==1:returnself.yelse:raiseIndexError("Indexoutofrange")

如今您可以经常使用索引访问这些元素,如下所示:

v=Vector2D(3,5)print(v[0])print(v[1])Output>>>35

10.__call__

借助__call__方法的成功,您可以像调用函数一样调用对象。

在Vector2D类中,咱们可以成功__call__,按给定因子缩放向量:

classVector2D:def__init__(self,x,y):self.x=xself.y=ydef__repr__(self):returnf"Vector2D(x={self.x},y={self.y})"def__call__(self,scalar):returnVector2D(self.x*scalar,self.y*scalar)

假设您如今调用3,会失掉缩放3倍的向量:

v=Vector2D(3,5)result=v(3)print(result)Output>>>Vector2D(x=9,y=15)

11.__getattr__

__getattr__方法用于失掉对象的特定属性的值。

就这个例子而言,咱们可以减少一个__getattr__dunder方法,一旦被调用可计算向量的量值(L2-norm):

classVector2D:def__init__(self,x,y):self.x=xself.y=ydef__repr__(self):returnf"Vector2D(x={self.x},y={self.y})"def__getattr__(self,name):ifname=="magnitude":return(self.x**2+self.y**2)**0.5else:raiseAttributeError(f"'Vector2D'objecthasnoattribute'{name}'")

无妨验证这能否像预期的那样上班:

v=Vector2D(3,4)print(v.magnitude)Output>>>5.0

论断

这就是本教程的所有内容!宿愿您曾经学会了如何为您的类减少魔术方法,以模拟内置函数的行为。

咱们已引见了一些最有用的魔术方法,但这并非详尽的清单。为了进一步了解,您可以创立一个所选用的Python类,依据所需的性能减少魔术方法。最后祝编程欢快!

原文题目: HarnessthePowerofAIforBusiness ,作者:BalaPriyaC


python调试程序BUG的心得技巧分享

【导读】相信各位Python工程师们在写Python代码的时候,免不了经常会出现bug满天飞这种情况,这个时候我们可能就得一个标点一个标点的去排查,费时又费力,但是,我们又很难发现到底是其中的哪一个步骤,导致了这些问题的出现。导致这些问题的其中一个原因,就是我们没有养成良好的编程习惯。编程习惯就好比是电影中的特效。电影特效越好,呈现出来的观影效果也自然越好。同样,如果我们能够养成好的编程习惯,在查找错误的时候,自己的思路就会更加清晰。下面是小编整理的解决Python项目bug的心得技巧分享,包含六小点,希望对大家有所帮助。

方法一:使用项目管理工具

无论Python项目简单与否,我们都应该使用Git进行版本控制。大部分支持Python的IDE(集成开发环境)都内置了对Git这一类项目管理工具的支持。

我们在修改代码时,常常会出现改着改着程序就崩了的情况,改出的最新版本有时候还不如上一个版本。而Git,恰好能够及时帮我们保存之前的版本。使用了它以后,我们也不需要不停地用“ctrl+z”来撤回代码了。

方法二:使用Python的内置函数

Python的内置函数和标准库都可以处理常见的用例,而不需要自己重新定义函数。

但是,刚刚入门的Python开发人员们对其中的函数并不熟悉。所以他们经常会遇到这样一个问题——在不需要记住内容的情况下,如何才能知道标准库中的内容是否涵盖了自己的用例?最简单的方法是将标准库索引和内置函数概述页添加为书签,并且在遇到“日常编程”类问题的时候立即浏览一下。我们使用这些函数的频率高了,自然也就能记住这些函数了。

方法三:使用正确的模块

与内置函数和标准库一样,Python中大量的第三方模块集合,也可以帮助我们节省大量的人力。通过PyPI的Web前端,可以针对我们的问题触发搜索词,我们很容易就能找到适合自己的解决方案。

方法四:使用OOP

面向对象编程(OOP)将数据结构与用于操作它们的方法捆绑在一起,从而使编写高级代码更加容易。OOP非常适合用于Python这一类高级语言,尤其是项目非常复杂的时候。熟悉Python的开发人员都知道,使用OOP可以减少代码量,从而节省大量的时间。

但是,也不是所有的项目都需要使用OOP。如果项目没有特别要求,一些小型的项目就可以不用OOP。

方法五:编写测试代码并不断测试

一个好的程序员一定知道测试之于项目的重要性。编写测试代码的确是一个很枯燥的过程,但是不进行测试,我们就无法发现程序的问题所在。

如果一个项目非常复杂的话,我们就必须要做到及时测试。越早测试,就能越早发现问题。而不是说等代码全部写完了,才开始进行测试,这样反而会导致更多的错误和更大的工作量。

当然,我们也可以寻找专业的软件测试人员,来帮助我们进行测试。这样我们也可以把更多的精力投入到项目程序本身。

方法六:选择正确的Python版本

部分人仍然在使用Python2,但Python官方的开发团队早已经不对这一版本进行维护了。聪明的开发人员都已经将Python2里的项目迁移到Python3中了。

Python目前的最新版本是Python3.8.5,但也不是说你一定要使用最新版本。专业的软件开发人员都知道,任何软件的最新版本都不一定是最好的,因为它仍需要开发团队不断地去改良。程序员一般都会使用在最新版本之前的一个版本,旧版本相对而言是比较成熟的。

无论是运用哪一种语言编写代码,优秀的程序员都具备良好的编程习惯。这些习惯不仅能够让我们思路更加清晰,也可以帮助我们减轻工作量,从而节省大量的时间。所以,可能你离优秀的程序员,只差一个好习惯了哦~

python编程:魔术方法

首先,你一定用过魔术方法,也一定见过魔术方法。以下划线开头的方法,比如:

这些被统称为魔术方法。

给整数和字符串做加法:

我们写个表示城市的类,它有两个属性:城市名和人口。

然后我们给两个城市做加法,发现不能相加:

报错是说City不支持+号,如何让它支持+呢?需要给类加上魔术方法__add__就可以相加了。

我们给City添加一个__add__的方法,城市相加,人口相加,创建一个新的城市:

这说明__add__有一定的魔力,当我们用到加号+时,python就回去寻找这个方法,如果这个对象没有这个方法就会报错。

python中,所有的运算符都是通过魔术方法来实现的。

如果我们在City类有以下方法,就可以做加减乘除了:

我们再来打印int和str查看他们的方法,int有加减乘除,str只有__add__ __mul__,它只能做加法和乘法:

列表为什么能获取元素, __getitem__,可以再任何一个类里加上这个方法,然后也就可以用[]方括号来获取元素:

我们使用最多的方法一定是__new__和__init__, 在新建方法的时候,都会调用到这两个方法:

不止有魔术方法,还有魔术属性,形如__yyy__,通常是python自动设置的属性,我们可以使用这些属性,比如:

什么使用str方法,什么时候用repr方法?

如果我们想让print打印出来好看,可以定义__str__的方法:

免责声明:本文转载或采集自网络,版权归原作者所有。本网站刊发此文旨在传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及版权、内容等问题,请联系本网,我们将在第一时间删除。同时,本网站不对所刊发内容的准确性、真实性、完整性、及时性、原创性等进行保证,请读者仅作参考,并请自行核实相关内容。对于因使用或依赖本文内容所产生的任何直接或间接损失,本网站不承担任何责任。

标签: Python

“Python-每个程序员都应该知道的-个-魔术方法-11 (python怎样打开)” 的相关文章

Python中的LEGB规则 (python怎样打开)

Python中的LEGB规则 (python怎样打开)

Python 中的 LEGB 规则决定了变量和函数的作用域解析顺序。它代表了四个作用域层级: 局部作用域 闭包函数外的函数 全局作用域 内置作用域...

处置日常义务的终极工具!-Python-文件读写实战 (处置行为是什么意思)

处置日常义务的终极工具!-Python-文件读写实战 (处置行为是什么意思)

/target=_blankclass=infotextkey>Python文件的读写操作时,有很多须要思考的细节,这包含文件关上形式、读取和写入数据的方法、意外处置等。 在本文中,...

Python中的Random模块-摸索随机性的神奇环球 (python编程)

Python中的Random模块-摸索随机性的神奇环球 (python编程)

随机性在计算机编程和数据迷信中表演着至关关键的角色。/target=_blankclass=infotextkey>Python中的random模块提供了丰盛的工具和函数,协助咱们生成随机数...

惰性求值和lambda表达式的强大组合-Python高级技巧 (惰性求值和逻辑短路)

惰性求值和lambda表达式的强大组合-Python高级技巧 (惰性求值和逻辑短路)

Lambda 表达式 在 Python 中,Lambda 表达式是一个匿名函数,它可以在需要函数对象的地方使用。Lambda 表达式的语法如下: lambda arguments: exp...

一份收藏者必备清单-100个精选Python库 (收藏者的心态)

一份收藏者必备清单-100个精选Python库 (收藏者的心态)

/target=_blankclass=infotextkey>Python为啥这么火,这么多人学,就是由于繁难好学,性能弱小,整个社区十分生动,资料很多。而且这言语触及了方方面面,比如智能...

轻松把握多线程和多进程-Python编程进阶 (多线是什么意思)

轻松把握多线程和多进程-Python编程进阶 (多线是什么意思)

1、简介 咱们将讨论如何应用/target=_blankclass=infotextkey>Python口头多线程和多进程义务。它们提供了在单个进程或多个进程之间口头并发操作的方法。并...

生成-UUID-操作-Python-齐全指南-格局和经常出现疑问 (生成uuid java)

生成-UUID-操作-Python-齐全指南-格局和经常出现疑问 (生成uuid java)

UUID(UniversallyUniqueIdentifier,通用惟一标识符)是一种全局惟一标识符生成形式,用于创立举世无双的标识符。/target=_blankclass=infotextk...

使用Python进行数据分析的步骤 (使用pycharm)

使用Python进行数据分析的步骤 (使用pycharm)

简介 Python 是一种动态的、面向对象的脚本语言,以其简单性和易读性而闻名。它广泛用于数据分析,因为它具有强大的库,兼容开源大数据平台 Hadoop,并且拥有众多优势,使其成为流行的编...