说明
《Python 教程》 持续更新中,提供建议、纠错、催更等加作者微信: gairuo123(备注:pandas教程)和关注公众号「盖若」ID: gairuo。跟作者学习,请进入 Python学习课程。欢迎关注作者出版的书籍:《深入浅出Pandas》 和 《Python之光》。
Python中实现切片功能的特殊方法主要是 __getitem__()
和 __setitem__()
。这两个方法分别用于获取和设置对象的元素。__getitem__()
方法允许对象以类似于列表的方式进行切片操作,而 __setitem__()
方法用于设置对象的元素值。另外,如果你需要支持删除操作,可以实现 __delitem__()
方法。
下面是这些方法的作用以及一个示例说明:
__getitem__(self, index)
: 该方法用于支持对象的切片操作,接收一个索引或者一个切片对象作为参数,根据参数返回相应的元素或者子序列。__setitem__(self, index, value)
: 该方法用于设置对象的元素值,接收一个索引和一个值作为参数,将指定索引处的元素设置为给定的值。__delitem__(self, index)
: 该方法用于删除对象的元素,接收一个索引作为参数,删除指定索引处的元素。a[1:2] = b
会为转写为 a[slice(1, 2, None)] = b
其他形式以此类推。略去的切片项总是以 None 补全。
object.__getitem__(self, key)
调用此方法以实现 self[key] 的求值。 对于 sequence 类型,接受的键应为整数。 作为可选项,它们也可能支持 slice 对象。 对负数索引的支持也是可选项。 如果 key 的类型不正确,则可能引发 TypeError。 如果 key 为序列索引集合范围以外的值(在进行任何负数索引的特殊解读之后),则应当引发 IndexError。 对于 mapping 类型,如果 key 找不到(不在容器中),则应当引发 KeyError。
备注 for 循环在有不合法索引时会期待捕获 IndexError 以便正确地检测到序列的结束。
备注 当 抽取 一个 class 时,可能会调用特殊类方法 __class_getitem__()
而不是 __getitem__()
。 请参阅 __class_getitem__
与 __getitem__
(https://docs.python.org/zh-cn/3/reference/datamodel.html#classgetitem-versus-getitem)了解详情。
object.__setitem__(self, key, value)
调用此方法以实现向 self[key]
赋值。注意事项与 __getitem__()
相同。为对象实现此方法应该仅限于需要映射允许基于键修改值或添加键,或是序列允许元素被替换时。不正确的 key 值所引发的异常应与 __getitem__()
方法的情况相同。
object.__delitem__(self, key)
调用此方法以实现 self[key] 的删除。注意事项与 __getitem__()
相同。为对象实现此方法应该权限于需要映射允许移除键,或是序列允许移除元素时。不正确的 key 值所引发的异常应与 __getitem__()
方法的情况相同。
下面是一个示例说明:
class CustomList:
def __init__(self, *args):
self.data = list(args)
def __getitem__(self, index):
if isinstance(index, slice):
start, stop, step = index.indices(len(self.data))
return [self.data[i] for i in range(start, stop, step)]
else:
return self.data[index]
def __setitem__(self, index, value):
self.data[index] = value
def __delitem__(self, index):
del self.data[index]
def __len__(self):
return len(self.data)
def __repr__(self):
return repr(self.data)
# 使用示例
custom_list = CustomList(1, 2, 3, 4, 5)
# 获取切片
print(custom_list[1:4]) # 输出 [2, 3, 4]
# 设置元素值
custom_list[1] = 10
print(custom_list) # 输出 [1, 10, 3, 4, 5]
# 删除元素
del custom_list[2]
print(custom_list) # 输出 [1, 10, 4, 5]
示例中,我们定义了一个自定义列表类 CustomList,并实现了 __getitem__()
、__setitem__()
和 __delitem__()
方法来支持切片操作、设置元素值和删除元素。通过这些方法,我们可以像操作普通列表一样操作 CustomList 类的实例。
创建一个包含日期范围的类,允许用户像使用列表一样对日期进行索引和切片操作。我们可以使用 Python 的 datetime 模块来处理日期。
from datetime import timedelta, datetime
class DateRange:
def __init__(self, start_date, end_date):
self.start_date = start_date
self.end_date = end_date
self.days = (end_date - start_date).days + 1
def __getitem__(self, index):
if isinstance(index, slice):
start = index.start or 0
stop = index.stop or self.days
step = index.step or 1
return [self.start_date + timedelta(days=i)
for i in range(start, stop, step)
]
else:
if index < 0:
index += self.days
if index < 0 or index >= self.days:
raise IndexError("Index out of range")
return self.start_date + timedelta(days=index)
# 使用示例
start_date = datetime(2024, 1, 1)
end_date = datetime(2024, 1, 10)
date_range = DateRange(start_date, end_date)
# 索引访问
print(date_range[0]) # 输出 2024-01-01
print(date_range[-1]) # 输出 2024-01-10
# 切片访问
print(date_range[1:5])
# 输出 [2024-01-02, 2024-01-03, 2024-01-04, 2024-01-05]
示例中,DateRange 类表示了一个日期范围,允许用户对日期范围进行索引和切片操作。通过实现 __getitem__()
方法,我们使得该类的实例支持了像列表一样的索引和切片操作,这样用户就可以方便地对日期范围进行处理。
https://docs.python.org/zh-cn/3/reference/datamodel.html#object.__getitem__
更新时间:March 4, 2024, 9 p.m. 标签:python 特殊方法 切片