Loading... >> Python中的序列类型接口协议被定义在了Sequence这个抽象基类中, 如果你需要自己定义一个类似queryset和df那种任意切片的序列对象, 可参照我这里的实现方式: >> > > **你需要清楚Python中的相关魔法方法:** `__getitem__`, 该方法,可以完成**迭代/切片** > > ```python > # author: Michael > # email: yangowen@126.com > > # Note: 要想实现可切片对象, 本质上就是实现序列类的接口协议 > # 在不可变序列抽象基类中 可查到序列类所必须要实现哪些接口, 可以继承它, 也可以不继承 > from collections.abc import Sequence > > > class WebSite(Sequence): > def __init__(self, roles, users: list): > self.roles = roles > self.users = users > > def __len__(self): > return len(self.users) > > def __getitem__(self, item): > cls = self.__class__ > # Note: [:3]是一个slice对象 > if isinstance(item, slice): > return cls(self.roles, self.users[item]) > # Note: [0]是一个int对象 > elif isinstance(item, int): > return cls(self.roles, [self.users[item], ]) > > def __contains__(self, item): > for v in self.users: > if v is item or v == item: > return True > else: > return False > def __reversed__(self): > self.users.reverse() > > def __iter__(self): > return iter(self.users) > > def __str__(self): > return str(self.users) > > > site = WebSite(['admin', 'guest'], ['a', 'b', 'c', 'd']) > print(site[:3], type(site[:3])) # 依然是WebSite类, 可继续做切片 > print(site[0], type(site[0])) > print(len(site)) # 4 > # reversed(site) # 对site做了翻转 > > if 'c' in site: # 触发__contain__ > print('yes') > > for i in site: # 触发__iter__ > print(i) > ``` © 允许规范转载