摘要:在中,特殊方法以双下划线开始,以双下划线结束。真假值,如果向量模为,返回实现向量加法实现向量乘法,例如返回向量的模返回欧几里德范数找个例子运行下。怎么办中有个特殊方法,可以修改控制台输出的样式。
什么是特殊方法?当我们在设计一个类的时候,python中有一个用于初始化的方法$__init__$,类似于java中的构造器,这个就是特殊方法,也叫作魔术方法。简单来说,特殊方法可以给你设计的类加上一些神奇的特性,比如可以进行python原生的切片操作,迭代、连乘操作等。在python中,特殊方法以双下划线开始,以双下划线结束。
一个大例子数学中有一个表示数的概念叫做向量,但是python中的数据类型却没有。我们来设法用python实现它。
首先考虑,向量跟普通的数据类型不同,传统的数可以直接进行运算,向量则需要对不同的坐标分别运算。来试试。
首先定义一个类,实现初始化方法。
# 实现向量类型 class Vector: def __init__(self, x=0, y=0): self.x = x self.y = y
如何实现向量的加法?二维向量中,向量的加法就是每个坐标分别相加得到的结果。在python中有个$__add__$方法,用来进行加法操作。
class Vector: def __init__(self, x=0, y=0): self.x = x self.y = y # 实现向量加法 def __add__(self, other): x = self.x + other.x y = self.y + other.y return Vector(x, y)
我们对x和y变量分别进行相加,然后返回Vector。在python你可以对字符串直接用加法拼接起来的原理就在此,python实现了针对字符串的add方法。
实现了加法,乘法的道理一样,分别对每个坐标多带带相乘即可。
class Vector: def __init__(self, x=0, y=0): self.x = x self.y = y # 实现向量加法 def __add__(self, other): x = self.x + other.x y = self.y + other.y return Vector(x, y) # 实现向量乘法,例如r*3 def __mul__(self, scalar): return Vector(self.x*scalar, self.y*scalar)
我们在进行向量运算时还有一个常用的操作是求向量的模,我们用$__abs__$特殊方法来实现,abs一般用来求一个数的绝对值,向量用不到,用来求模刚好合适。使用math模块中的hypot方法计算$sqrt(x^2+y^2)$。
class Vector: def __init__(self, x=0, y=0): self.x = x self.y = y # 真假值,如果向量模为0,返回false def __bool__(self): return bool(abs(self)) # 实现向量加法 def __add__(self, other): x = self.x + other.x y = self.y + other.y return Vector(x, y) # 实现向量乘法,例如r*3 def __mul__(self, scalar): return Vector(self.x*scalar, self.y*scalar) # 返回向量的模 # hypot()返回欧几里德范数 sqrt(x*x + y*y) def __abs__(self): return hypot(self.x, self.y)
找个例子运行下。
v = Vector(2, 3) print(v) v2 = Vector(4, 5) print(v+v2) print(v+v2*2)
<__main__.Vector object at 0x000002B4B1843C50> <__main__.Vector object at 0x000002B4B1843EF0> <__main__.Vector object at 0x000002B4B1843898>
可以运行了,貌似是正确的,但是输出的结果很奇怪。怎么办?python中有个$__repr__$特殊方法,可以修改控制台输出的样式。
class Vector: def __init__(self, x=0, y=0): self.x = x self.y = y # 真假值,如果向量模为0,返回false def __bool__(self): return bool(abs(self)) # 实现向量加法 def __add__(self, other): x = self.x + other.x y = self.y + other.y return Vector(x, y) # 实现向量乘法,例如r*3 def __mul__(self, scalar): return Vector(self.x*scalar, self.y*scalar) # 返回向量的模 # hypot()返回欧几里德范数 sqrt(x*x + y*y) def __abs__(self): return hypot(self.x, self.y) # 实现__repr__方法,在控制台打印向量时会输出Vector(1, 2) # 实现__str__,使用str()返回字符串 def __repr__(self): return "Vector(%r, %r)" % (self.x, self.y)
实现了$__repr__$方法,我们就可以在控制台输出Vecotor(x,y)。与之对应的有个$__str__$方法,使用str()返回相应的字符串,展示给用户。
现在来看下之前程序运行的结果。
v = Vector(2, 3) print(v) v2 = Vector(4, 5) print(v+v2) print(v+v2*2) print(abs(v))
Vector(2, 3) Vector(6, 8) Vector(10, 13) 3.605551275463989
效果不错。
通过实现特殊方法,自定义类型可以表现的跟内置类型一样,让我们能够写出更具有python风格的代码。
除了上面说到的几个特殊方法外,python还有差不多80多个特殊方法,比如$__len__$方法可以用来求长度,$__getitem__$可以使用haha[2]之类的操作进行切片和迭代等,同样的还有$__setitem__$。
本人才疏学浅,上文中难免有些错误,还请各位品评指正。如果觉得写的还行,欢迎关注我的公众号MLGroup,带你走进机器学习的世界。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/44516.html
摘要:找出列表中小于的数据除了列表推导式,还有字典推导式,集合推导式,用法都一样。如果你的数据量很大的话,考虑使用生成器表达式。切片不仅对列表有用,同样适用于元组和字符串。切片命名使用方法,内部参数与切片一样。对剩余的的数据,使用星号代替即可。 上次我们讲了几个不常见的数据类型,每个都有自己特殊的用途,虽然不经常用到,了解一下也好。比如我们提到的数组类型,如果在数据量很大的时候同时要效率,就...
摘要:字典和集合都是基于散列表实现的,散列表也就是表,了解过数据结构的应该知道。而使用另一种办法,任何键在找不到的情况下都会用中的值数据类型比如替换。在设计时就可以使用创建你的数据接口。 这次主要说说字典和集合这两种数据类型。 字典和集合都是基于散列表实现的,散列表也就是hash表,了解过数据结构的应该知道。与散列表相关的一个概念叫做可散列,什么是可散列?在python官方定义中是这样说的:...
摘要:挤掉了堆中实现了堆排序。你可以用堆排序来查找一个序列中最大的或者最小的几个元素。除了使用堆排序,中还有排序和,这两个排序最终生成以列表表示的排序结果,堆排序也是。 这次我们来说说python中的数据结构。当然了,不会讲很基础的内容。 用过python的都知道,python有着与其他语言很不一样的数据类型,像什么列表、元组、集合、字典之类。这些数据类型造就了python简单易用同时又很强...
摘要:来说说迭代器和生成器,还有可迭代对象和生成器表达式。有点绕是不是,其实,一般只要知道可迭代对象以及它是如何实现的就行了,中常常用生成器来代替迭代器,可以说,生成器就是迭代器。 来说说迭代器和生成器,还有可迭代对象和生成器表达式。 之前简单的提到过,一个对象是可迭代的可以理解为能够使用for循环。这样说其实不太准确,某个对象可迭代是因为它内部实现了$__iter__$这个特殊方法。比如在...
摘要:先不讲数据结构了,这次来说说中一些不被注意的功能。直接交换第二个功能。对的长度使用生成一个序列,然后遍历或者这样第三个功能。其实还接受第二个参数,它的作用是在迭代的过程中如果碰到第二个参数则停止。 先不讲数据结构了,这次来说说python中一些不被注意的功能。 在python的设计哲学中,有这么一条内容:Simple is better than complex,简单的代码比复杂的要好...
阅读 3690·2021-11-24 09:39
阅读 1850·2021-11-16 11:45
阅读 592·2021-11-16 11:45
阅读 1004·2021-10-11 10:58
阅读 2446·2021-09-09 11:51
阅读 1925·2019-08-30 15:54
阅读 666·2019-08-29 13:13
阅读 3450·2019-08-26 12:18