当我们在Python中定义一个类时,如果该类想具备可迭代性,那么就需要实现__getitem__
方法。
1. __getitem__
方法用法
__getitem__(self, index)
函数,是Python内置函数,用于索引操作符[]使用。
如果在一个类中定义了该方法,则可以像索引操作符一样使用它来获得指定位置的元素或切片。
下面是一个简单的例子:
class MyList:
def __init__(self):
self.items = []
def __getitem__(self, index):
if isinstance(index, int):
return self.items[index]
if isinstance(index, slice):
# 传入的是切片,则返回切片范围内的列表
start = index.start if index.start else 0
end = index.end if index.end else len(self.items)
step = index.step if index.step else 1
return [self.items[i] for i in range(start, end, step)]
raise TypeError('Invalid index type')
my_list = MyList()
my_list.items = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print(my_list[0]) # 0
print(my_list[-1]) # 9
print(my_list[1:6]) # [1, 2, 3, 4, 5]
上述代码创建了一个MyList
的类,实现了__getitem__
方法,并可以用于获取列表中指定位置的元素,或者用于获取指定范围的子列表。我们使用该类MyList
创建一个实例,并对实例使用切片的方式进行索引,输出了相应的结果。
2. __getitem__
方法两个示例
2.1 示例1:模拟python的range函数
Python内置函数range用于生成一个指定范围内的整数列表。因此,可以利用__getitem__
方法从指定的范围上获取一个整数列表。
例如,下列代码演示了如何实现一个类MyRange
,其__getitem__
方法可以用于模拟Python内置函数range的功能:
class MyRange:
def __init__(self, start, end, step=1):
self.start = start
self.end = end
self.step = step
def __getitem__(self, index):
if isinstance(index, int):
# 模块1:返回单个数值
i = self.start + index * self.step
if i < self.end:
return i
else:
raise IndexError('Index out of range')
elif isinstance(index, slice):
# 模块2:返回一个可迭代对象
start, stop, step = index.indices(self.calculate_length())
rng = [self.start + i * self.step for i in range(start, stop, step)]
return rng
raise TypeError('Invalid index type')
def __len__(self):
return self.calculate_length()
def calculate_length(self):
if self.start < self.end and self.step > 0:
return ((self.end - self.start - 1) // self.step) + 1
elif self.start > self.end and self.step < 0:
return ((self.start - self.end - 1) // (-self.step)) + 1
else:
return 0
r = MyRange(10, 20, 2)
print(r[1]) # 12,获取指定单个整数值
print(r[:]) # [10, 12, 14, 16, 18] 获取所有的整数列表
print(r[0:3]) # [10, 12, 14] 获取指定长度的整数列表
上述代码中创建了一个名称为MyRange
的类,其构造函数可用于指定范围并返回一个迭代器,该迭代器可以按指定的步长获得连续的整数值。计算每个单独的整数值,我们将首个整数值设置为start
,然后将index
乘以step
并将其添加到其上,从而得到所需的整数值。最后,将整数值附加到一个列表中,并返回。
2.2 示例2:模拟Python中的字典
另一个示例可能会更直观:如何实现一个能够适应需求的字典?
这里,实现的字典类MyDict
,将键值对存储在列表中,在通过索引操作符访问某个键对应的项时,先遍历整个列表,根据所给出的key值找到对应的value值并返回。
class MyDict:
def __init__(self, data={}):
self.data = data
def __getitem__(self, key):
for k, v in self.data:
if k == key:
return v
raise KeyError(f"KeyError: {key}.")
def __setitem__(self, key, value):
for i, item in enumerate(self.data):
k, v = item
if k == key:
self.data[i] = (key, value)
break
else:
self.data.append((key, value))
def __delitem__(self, key):
for i, item in enumerate(self.data):
k, v = item
if k == key:
del self.data[i]
break
else:
raise KeyError(f"KeyError: {key}.")
md = MyDict([('a', 1), ('b', 2), ('c', 3)])
print(md['b']) # 2
md['d'] = 4
print(md['d']) # 4
del md['a']
print(md['a']) # KeyError: 'a'
上述代码中,在__getitem__
中,我们没有直接使用key
取得value值,而是遍历整个列表,找到匹配的key值后,再返回value值。
在__setitem__
中,我们检查列表中是否存在key,若不存在则将新的key-value对加入列表。若存在则将其更新。
在__delitem__
中,我们检查列表中是否存在key,若存在则删除它。
通过此处的示例,可以看到__getitem__
方法的灵活性和高度定制化。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:python __getitem__使用方法详解 - Python技术站