简介:for循环遍历对象中的属性值实现原理,对象切片截取实现原理,对象反转实现原理
之前的文章中我们介绍过for/in遍历,但是之前遍历的都是列表,元组等数据结构。那么for/in能不能遍历对象呢?
事实上对象也是可以遍历的,而且之前所介绍的列表,元组,集合等,其实都是对象,那么他们是怎么实现遍历对象的呢?为什么我们自己写的对象无法遍历?
1. 实现原理
在python中如果我们想要遍历一个对象,只需要在对象中实现 __getitem__ 魔术方法即可。for/in遍历对象时会去调用这个魔术方法获取遍历后的单个元素,具体实现方式如下:
class PeoploContainer():
def __init__(self,peoples):
self.container = peoples
# 切片(包含for/in遍历)魔法方法
def __getitem__(self,item):
return self.container[item]
peoples = PeoploContainer(['tom','bob','jane'])
# 遍历
for people in peoples:
print(people) # 打印结果:tom bob jane
2. 截取
上面介绍的 __getitem__ 魔法方法其实是一个切片魔法方法,这个方法除了可以实现for/in遍历之外,其实也可以实现截取功能,毕竟截取和for/in遍历都是从列表中读取一个或若干个元素。具体实现如下所示:
class PeoploContainer():
def __init__(self,peoples):
self.container = peoples
# 魔术方法
def __item__(self,item):
return self.container[item]
peoples = PeoploContainer(['tom','bob','jane'])
# 截取
print(peoples[:2]) # 打印结果:['tom', 'bob']
__item__参数 item:通过peoples[0]获取某个元素时以及for/in遍历时,item是一个 int 类的值也就是索引
但是如果我们通过peoples[0:2]进行截取时,item是一个 slice 类的值
3. 获取对象的长度
平时使用 len() 函数可以获取列表、元组及集合等基础数据结构的长度,那么我们可不可以使用 len() 函数获取某个对象的长度呢?
当然可以,我们只需要在对象中定义 __len__ 魔法方法,在这个魔法方法中使用 len() 获取某个变量的长度即可。如果没有定义该魔法函数使用 len() 获取对象的长度会直接报错哦。具体实现代码如下:
class PeoploContainer():
def __init__(self,peoples):
self.container = peoples
# 获取长度的魔法方法
def __len__(self):
return len(self.container)
peoples = PeoploContainer(['tom','bob','jane'])
print(len(peoples)) #打印结果:3
4. 使用 in 判断某个元素是否在对象中
我们使用 in 判断某个元素是否在对象的某个容器中时,会调用对象的 __contains__ 魔法方法,因此,我们只需要实现该魔法方法即可。具体代码如下:
class PeoploContainer():
def __init__(self,peoples):
self.container = peoples
# in相关魔法方法
def __contains__(self,item):
return True if item in self.container else False
peoples = PeoploContainer(['tom','bob','jane'])
print('tom' in peoples) # 打印结果:True
__contains__参数item:待判断的值
5. 数据反转
和上面一样,只需要实现 reversed() 函数对应的魔法方法 __reversed__ 即可。并且这个魔法函数没有返回值,直接使用reverse() 使对象某个属性的值进行反转即可。具体实现代码如下所示:
class PeoploContainer():
def __init__(self,peoples):
self.container = peoples
# 数据反转相关的魔法方法
def __reversed__(self):
self.container.reverse()
peoples = PeoploContainer(['tom','bob','jane'])
# 数据反转
reversed(peoples)
# 反转后的数据
print(peoples.container) # 打印结果:['jane', 'bob', 'tom']
介绍到这里,大家应该有所发现,所有python内置的数据结构相关函数,在对象中都有与之对应的魔法方法进行操作。事实上,所有的基础数据结构都是对象,他们的对象内部其实就是实现了与之对应的魔法方法,使得我们可以使用 len() 等函数操作基础数据结构。
有遗漏或者不对的可以在我的公众号留言哦