特殊方法----getitem()
Python的特殊方法__getitem_() 主要作用是可以让对象实现迭代功能。我们通过一个实例来说明。
定义一个Sentence类,通过索引提取单词。
import re
RE_WORD = re.compile(r'\w+')
class Sentence:
def __init__(self, text):
self.text = text
self.words = RE_WORD.findall(text) # re.findall函数返回一个字符串列表,里面的元素是正则表达式的全部非重叠匹配
def __getitem__(self, index):
return self.words[index]
- 测试
>>> s = Sentence('The time has come')
>>> for word in s:
print(word)
The
time
has
come
>>> s[0]
'The'
>>> s[1]
'time'
通过测试发现,示例 s 可以正常迭代。但是没有定义 getitem() 测试则会报错, TypeError: '***' object is not iterable
。
序列可以迭代
我们都知道序列是可以迭代,下面具体说明原因。
解释器需要迭代对象x时, 会自动调用iter(x)
方法。内置的 iter(x)
方法有以下作用
- 检查对象是否实现了
__inter__
方法,如果实现了就调用它(也就是我们偶尔用到的特殊方法重载),获取一个迭代器。 - 如果没有实现
iter()
方法, 但是实现了__getitem__
方法,Python会创建一个迭代器,尝试按顺序(从索引0开始,可以看到我们刚才是通过s[0]取值)获取元素。 - 如果尝试失败,Python抛出TypeError异常,通常会提示
TypeError: '***' object is not iterable
。
任何Python序列都可迭代的原因是,他们都实现了__getitem__
方法。其实,标准的序列也都实现了 __iter__
方法。
注意: 从python3.4 开始,检查对象x能否迭代,最准确的方法是: 调用iter(x)
方法,如果不可迭代,在处理TypeError异常。这比使用isinstance(x,abc.Iterable)
更准确,因为iter()
方法会考虑到遗留的__getitem__()
方法,而abc.Iterable
类则不考虑。