我们今天聊聊怎么使用python中的特殊方法来实现属于自己的数据类型。
python中有很多的数据类型,比如说数组、字典等等。
我们先来看一个例子,我们平时使用 len()
这个函数的次数很多,它会获取对象的长度:
>>> a = [1,2,3,4]
>>> len(a)
4
但当我们把len()
应用到整数上时就会报错:
>>> a = 3
>>> len(a)
TypeError: object of type 'int' has no len()
为什么会出现这个结果呢?
Python 解释器碰到特殊的句法时(例如
len()
),会使用特殊方法去激活一些基本的对象操作,这些特殊方法的名字以两个下划线开头,以两个下划线结尾(例如__len__
)。
我们在使用 len()
这个函数的时候,解释器会去调用__len__
方法。而由于 int 中没有内嵌__len__
这个方法,所以代码会显示报错。
我们来自己实现一个例子看一看。我们现在自己构造一个Test类
class Test:
def __init__(self,nums):
self.nums = nums
这时候我们调用len()
函数
>>> test = Test([1,2,3,4])
>>> len(test)
TypeError: object of type 'Test' has no len()
我们发现同样会报错。但是我们接下来在 Test 类中加入__len__
方法试一下
class Test:
def __init__(self,nums):
self.nums = nums
def __len__(self):
return len(self.nums)
我们进行调用:
>>> test = Test([1,2,3,4])
>>> len(test)
4
我们发现程序可以正确返回我们想要的结果。当然我们可以尝试更骚的操作,在我们定义的数据类型里,无论你输入的值是什么,返回长度的时候总是返回1
class Test:
def __init__(self,nums):
self.nums = nums
def __len__(self):
return 1
我们试一下
>>> test1 = Test([1,2,3,4])
>>> len(test1)
1
>>> test2 = Test([1,2,3,4,5])
>>> len(test2)
1
我们发现其完美实现了我们想要的功能。
接下来我们再看:
>>> a = [1,2,3,4]
>>> a
[1, 2, 3, 4]
我们发现当我们给a赋值为list的时候,再次输入a,可以在屏幕上打印出a所显示的具体内容。
我们再来试试我们自己创建的类:
>>> test = Test([1,2,3,4])
>>> test
<__main__.Test at 0x7f8d5b6202d0>
我们发现当我们打印 test,得到的却是一串字符串,其可读性是比较差的。别人有的,我们也要有!我们有没有办法给我们自己创建的数据类型一个较好的表示形式呢?
答案是有的,就是__repr__
方法。我们来尝试一下
class Test:
def __init__(self,nums):
self.nums = nums
def __len__(self):
return len(self.nums)
def __repr__(self):
return '%r' %self.nums
>>> test = Test([1,2,3,4])
>>> test
[1, 2, 3, 4]
>>> print(test)
[1, 2, 3, 4]
我们用__repr__
方法完美解决了这个需求。
那如果我们也想要我们的数据结构有加法的功能呢?我们可以使用__add__
方法来实现!我们来看:
class Test:
def __init__(self,nums):
self.nums = nums
def __len__(self):
return len(self.nums)
def __repr__(self):
return '%r' %self.nums
def __add__(self, others):
_sum = [x+y for x, y in zip(self.nums, others.nums)]
return Test(_sum)
>>> a = Test([1,2,3,4])
>>> b = Test([1,2,3,4])
>>> a + b
[2, 4, 6, 8]
更进一步,如果我们想要实现乘法呢?只需要用到 __mul__
方法就可以:
class Test:
def __init__(self,nums):
self.nums = nums
def __len__(self):
return len(self.nums)
def __repr__(self):
return '%r' %self.nums
def __add__(self, others):
_sum = [x+y for x, y in zip(self.nums, others.nums)]
return Test(_sum)
def __mul__(self, scalar):
return Test([x*scalar for x in self.nums])
>>> a = Test([1,2,3,4])
>>> a*3
[3, 6, 9, 12]
当然,python中还存在很多其他特殊方法,比如说大家可以自己去探索!传送门 通过这些特殊方法,我们完全可以构造我们自己想要的数据类型,定义我们想要的数据运算方式。你想要它怎样,它就会怎样😜