之前我也介绍过一个魔法函数getitem是可以改变对象的类型。
为了实现可切片的对象,我不能一步就告诉你结果,这样你理解起来
一定很困难。我慢慢的引导,跟着我的思维走就行了。
1.返回list
from collections.abc import *
class Group(Sequence):
def __init__(self,school,grade,students):
self.school=school
self.grade=grade
self.students=students
#我们要把 Sequence 本身和它自身继承的父类的抽象方法都需要重写 下边的都是
def __reversed__(self):
pass
def __len__(self):
pass
def __getitem__(self, item): #这个是我们操作的关键所在,会返回一个list
return self.students[item]
def __iter__(self):
pass
def __contains__(self, item):
pass
a=["maggie",'Xiuwu','Andy']
name=Group('清华','2班',a)
sub_name=name[:]
print(name[:])
['maggie', 'Xiuwu', 'Andy']
2.返回切片对象
大家看看它返回的类型是一个lsit,同学们说了
我们要返回是一个切片对象,你给我list 有什么用,况且也是students的list
不要捉急呢,上边的代码只是让我们带入境界,已经完成实现主题。
下边都是对getitem 重写
我们一起看下我们要做到getitem支持两种类型:
- 一个是切片,如name[:]
其中 这个[:] 是slice 类型,并且 是需要传给 getitem() - 另一个是name[2]
其中 2 数numbers 类型。我们将会对这两种类型进行操作。
代码如下:
from collections.abc import *
import numbers
class Group(Sequence):
def __init__(self,school,grade,students):
self.school = school
self.grade=grade
self.students=students
#我们要把 Sequence 本身和它自身继承的父类的抽象方法都需要重写
def __reversed__(self):
pass
def __len__(self):
pass
def __getitem__(self, item):
cls=type(self)
if isinstance(item,slice):
return cls( school=self.school,grade=self.grade, students=self.students[item]) #这里就是返回的切片的students
if isinstance(item,numbers.Integral):
return cls( school=self.school,grade=self.grade, students=[self.students[item]]) #接受的是数组,所以要加上[]
def __iter__(self):
pass
def __contains__(self, item):
pass
a=["maggie",'Xiuwu','Andy']
name=Group('清华','2班',a)
sub_name=name[:] #通过debug 可以查看是Group 类型
print(name[0]) #通过debug 可以查看是Group 类型
pass
通过这样的操作,已经实现了 返回可切片对象 。
3.重写魔法函数
细心的小伙伴已经发现了,还有几个重写的方法,直接用pass
一笔带过,既然让你重写必然有其用处,怎么就不重写了。
是不是技术不够了。被鄙视了,看来我要一展身手,请看下边的代码
def __reversed__(self):#做反转
self.students.reverse()
def __len__(self): #取长度
return len(self.students)
def __iter__(self): #可以调用for 循环
return iter(self.students)
def __contains__(self, item): #可以调用 if --- in : 语句
if item in self.students:
return True
else:
return False
a=["maggie",'Xiuwu','Andy']
name=Group('清华','2班',a)
sub_name=name[:]
print(len(sub_name))
for i in sub_name:
print(i)
reversed(sub_name)
for i in sub_name:
print(i)
if "maggie" in sub_name:
print("yess")
打印结果
maggie
Xiuwu
Andy
Andy
Xiuwu
maggie
yess
总结:
对象切片之后还是切片对象关键点要重写 魔法函数getitem 。
要考虑两种情况:
当item 是切片类型(slice),
另一种情况是numbers 类型。
注意return 要是class 的类型,这样返回是类对象,
numbers时候 切记返回的都是数组例如上边的代码(students=[self.students[item]]) )。
对其他的魔法函数重写,能实现类对象对魔法函数的调用。
例如: reversed ,iter,len,contains 并且要知道重写后的意义。
(如有不足或者欠缺要及时提出,我感激不尽 谢谢)