什么是特殊方法?当咱们在设计一个类的时候,python中有一个用于初始化的方法$__init__$,相似于java中的构造器,这个就是特殊方法,也叫做魔术方法。简单来讲,特殊方法能够给你设计的类加上一些神奇的特性,好比能够进行python原生的切片操做,迭代、连乘操做等。在python中,特殊方法以双下划线开始,以双下划线结束。java
数学中有一个表示数的概念叫作向量,可是python中的数据类型却没有。咱们来设法用python实现它。python
首先考虑,向量跟普通的数据类型不一样,传统的数能够直接进行运算,向量则须要对不一样的坐标分别运算。来试试。机器学习
首先定义一个类,实现初始化方法。学习
# 实现向量类型 class Vector: def __init__(self, x=0, y=0): self.x = x self.y = y
如何实现向量的加法?二维向量中,向量的加法就是每一个坐标分别相加获得的结果。在python中有个$__add__$方法,用来进行加法操做。spa
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方法。scala
实现了加法,乘法的道理同样,分别对每一个坐标单独相乘便可。设计
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)$。code
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,带你走进机器学习的世界。