No.序列类型的特定协议
1. 序列操作中+,+=,extend的区别
1.1 + 操作与 +=的区别
1.1.1 +操作
sequence = [1,2,3]
sequence = sequence + [4,5,6]
print(sequence)
# [1, 2, 3, 4, 5, 6]
sequence = [1,2,3]
sequence = sequence + (4,5,6)
#Traceback (most recent call last):File #"D:/WeChatHandler/sequenceHandler.py", line 57, in <module>
#sequence = sequence + (4,5,6)
#TypeError: can only concatenate list (not "tuple") to list
1.1.2 +=操作
sequence = [1,2,3]
sequence += [4,5,6]
print(sequence)
# [1, 2, 3, 4, 5, 6]
sequence = [1,2,3]
sequence += (4,5,6)
print(sequence)
#[1, 2, 3, 4, 5, 6]
原因解析
+= 操作实际上是实现 “iadd” 协议,该协议调用了extend方法,将传入的可迭代对象的只遍历之后调用append方法添加到原序列
def __iadd__(self, values):
self.extend(values)
return self
def extend(self, values): #values :可迭代序列
for v in values:
self.append(v)
2. 可切片序列的原理
只要对象中实现了__getitem__协议那么就可以实现切片的操作,本质就是向__getitem__中传递了slice对象,并返回一个列表
class HasSlice :
def __init__(self, sequence):
self._sequence = sequence
def __getitem__(self, item):
return self._sequence[item]
s = HasSlice([1,2,3,4])
s[:2]
2.2 同时实现切片与返回指定值
from numbers import Integral
class Isslice :
def __init__(self,sequence):
self._sequence = sequence
def __getitem__(self, item):
cls = type(self) #利用元类创建一个新的类
if isinstance(cls,slice) :
return cls(self._sequence[item])
if isinstance(cls,Integral) :
return cls([self._sequence[item]])