è¿ä»£å¨ (Iterator)
====
# è¿ä»£åå¯è¿ä»£
è¿ä»£å¨è¿ä¸ªæ¦å¿µå¨å¾å¤è¯è¨ä¸ï¼æ¯å¦ C++ï¼Javaï¼é½æ¯åå¨çï¼ä½æ¯ä¸åè¯è¨å®ç°è¿ä»£å¨çæ¹å¼åä¸ç¸åã**å¨ Python ä¸ï¼è¿ä»£å¨æ¯æéµå¾ªè¿ä»£å¨åè®®ï¼iterator protocolï¼ç对象ã**è³äºä»ä¹æ¯è¿ä»£å¨åè®®ï¼ç¨åèªç¶ä¼è¯´æãä¸ºäºæ´å¥½å°çè§£è¿ä»£å¨ï¼æå
ä»ç»åè¿ä»£å¨ç¸å
³ç两个æ¦å¿µï¼
- è¿ä»£ï¼Iterationï¼
- å¯è¿ä»£å¯¹è±¡ï¼Iterableï¼
ä½ å¯è½ä¼è§å¾è¿æ¯å¨ç©æå游æï¼ä½è¿ç¡®å®æ¯è¦ææ¸
æ¥çã
> 彿们ç¨ä¸ä¸ªå¾ªç¯ï¼æ¯å¦ for 循ç¯ï¼æ¥éå容å¨ï¼æ¯å¦å表ï¼å
ç»ï¼ä¸çå
ç´ æ¶ï¼è¿ç§éåçè¿ç¨å°±å«***è¿ä»£***ã
å¨ Python ä¸ï¼æä»¬ä½¿ç¨ `for...in...` è¿è¡è¿ä»£ãæ¯å¦ï¼éåä¸ä¸ª list:
```python
numbers = [1, 2, 3, 4]
for num in numbers:
print num
```
åä¸é¢è¿ç§å¯ä»¥ä½¿ç¨ `for` 循ç¯è¿è¡è¿ä»£ç对象ï¼å°±æ¯å¯è¿ä»£å¯¹è±¡ï¼å®çå®ä¹å¦ä¸ï¼
> 嫿 `__iter__()` æ¹æ³æ `__getitem__()` æ¹æ³ç对象称ä¹ä¸º***å¯è¿ä»£å¯¹è±¡***ã
æä»¬å¯ä»¥ä½¿ç¨ Python å
ç½®ç `hasattr()` 彿°æ¥å¤æä¸ä¸ªå¯¹è±¡æ¯ä¸æ¯å¯è¿ä»£çï¼
```python
>>> hasattr((), '__iter__')
True
>>> hasattr([], '__iter__')
True
>>> hasattr({}, '__iter__')
True
>>> hasattr(123, '__iter__')
False
>>> hasattr('abc', '__iter__')
False
>>> hasattr('abc', '__getitem__')
True
```
å¦å¤ï¼æä»¬ä¹å¯ä½¿ç¨ `isinstance()` è¿è¡å¤æï¼
```python
>>> from collections import Iterable
>>> isinstance((), Iterable) # å
ç»
True
>>> isinstance([], Iterable) # å表
True
>>> isinstance({}, Iterable) # åå
¸
True
>>> isinstance('abc', Iterable) # å符串
True
>>> isinstance(100, Iterable) # æ°å
False
```
å¯è§ï¼æä»¬çç¥çåå
¸ï¼dictï¼ãå
ç»ï¼tupleï¼ãéåï¼setï¼ååç¬¦ä¸²å¯¹è±¡é½æ¯å¯è¿ä»£çã
# è¿ä»£å¨
ç°å¨ï¼è®©æä»¬ççä»ä¹æ¯è¿ä»£å¨ï¼Iteratorï¼ãä¸æè¯´è¿ï¼**è¿ä»£å¨æ¯æéµå¾ªè¿ä»£å¨åè®®ï¼iterator protocolï¼ç对象ã**ä»è¿å¥è¯æä»¬å¯ä»¥ç¥éï¼è¿ä»£å¨æ¯ä¸ä¸ªå¯¹è±¡ï¼ä½æ¯è¾ç¹å«ï¼å®éè¦éµå¾ªè¿ä»£å¨åè®®ï¼é£ä»ä¹æ¯è¿ä»£å¨åè®®å¢ï¼
> ***è¿ä»£å¨åè®®ï¼iterator protocolï¼***æ¯æè¦å®ç°å¯¹è±¡ç `__iter()__` å `next()` æ¹æ³ï¼æ³¨æï¼Python3 è¦å®ç° `__next__()` æ¹æ³ï¼ï¼å
¶ä¸ï¼`__iter()__` æ¹æ³è¿åè¿ä»£å¨å¯¹è±¡æ¬èº«ï¼`next()` æ¹æ³è¿å容å¨çä¸ä¸ä¸ªå
ç´ ï¼å¨æ²¡æåç»å
ç´ æ¶æåº `StopIteration` å¼å¸¸ã
æ¥ä¸æ¥è®²è®²è¿ä»£å¨çä¾åï¼æä»ä¹å¸¸è§çè¿ä»£å¨å¢ï¼å表æ¯è¿ä»£å¨åï¼åå
¸æ¯è¿ä»£å¨åï¼æä»¬ä½¿ç¨ `hasattr()` è¿è¡å¤æï¼
```
>>> hasattr((1, 2, 3), '__iter__')
True
>>> hasattr((1, 2, 3), 'next') # æ __iter__ æ¹æ³ä½æ¯æ²¡æ next æ¹æ³ï¼ä¸æ¯è¿ä»£å¨
False
>>>
>>> hasattr([1, 2, 3], '__iter__')
True
>>> hasattr([1, 2, 3], 'next')
False
>>>
>>> hasattr({'a': 1, 'b': 2}, '__iter__')
True
>>> hasattr({'a': 1, 'b': 2}, 'next')
False
```
åæ ·ï¼æä»¬ä¹å¯ä»¥ä½¿ç¨ `isinstance()` è¿è¡å¤æï¼
```
>>> from collections import Iterator
>>>
>>> isinstance((), Iterator)
False
>>> isinstance([], Iterator)
False
>>> isinstance({}, Iterator)
False
>>> isinstance('', Iterator)
False
>>> isinstance(123, Iterator)
False
```
å¯è§ï¼**è½ç¶å
ç»ãå表ååå
¸ç对象æ¯å¯è¿ä»£çï¼ä½å®ä»¬å´ä¸æ¯è¿ä»£å¨ï¼**对äºè¿äºå¯è¿ä»£å¯¹è±¡ï¼å¯ä»¥ä½¿ç¨ Python å
ç½®ç `iter()` 彿°è·å¾å®ä»¬çè¿ä»£å¨å¯¹è±¡ï¼çä¸é¢ç使ç¨ï¼
```
>>> from collections import Iterator
>>> isinstance(iter([1, 2, 3]), Iterator) # ä½¿ç¨ iter() 彿°ï¼è·å¾è¿ä»£å¨å¯¹è±¡
True
>>> isinstance(iter('abc'), Iterator)
True
>>>
>>> my_str = 'abc'
>>> next(my_str) # my_str 䏿¯è¿ä»£å¨ï¼ä¸è½ä½¿ç¨ next()ï¼å æ¤åºé
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)