[python] Jakého typu je iterátor?

Petr Prikryl PrikrylP na skil.cz
Úterý Duben 10 08:38:08 CEST 2007


Michal Vyskocil
> jakeho typu je vlastně iterator? V modulu types je 
> ani ve verzi 2.4, ani ve 2.5 nevidím. Ani mechanicke
> porovnani typu mi nevrati nic. Pritom generatory,
> ktere jsou iteratorum podobne, v modulu types jsou ...
> [...] 
> Myslite, ze je to chyba v Pythonu, nebo jsou uz 
> iteratory deprecated a nikoho nezajimaji?

"Iterátor" je především koncept. V jiných jazycích
byste mohl položit podobnou otázku "Jakého typu
je ukazatel?".

Na iterátoru je podstatné chování a nikoliv typ.
Typ může být různý. Důležité je dodržení dohodnutého
protokolu (tedy rozhraní a chování): poskytnutí
hodnoty z procházené (iterované) kolekce 
a signalizace dokončení průchodu celou kolekcí.
Příklad typů iterátorů pro základní pythonovské
datové typy:

>>> i = iter([1, 2, 3,])
>>> i
<listiterator object at 0x00A356F0>
>>> i = iter('abc')
>>> i
<iterator object at 0x00A35570>
>>> i = iter({'a': 1, 'b': 2})
>>> i
<dictionary-keyiterator object at 0x00A356E0>

Iterátory v čistém slova smyslu jsou spojeny
se skutečnými kolekcemi a zpřístupňují objekty
do nich zařazené. Generátory jsou výhodným
zobecněním. Liší se tím, že vracejí hodnoty
fiktivní kolekce, potenciálně nekonečné:

>>> def g():
...     n = 0
...     while True:
...         yield n
...
>>> g
<function g at 0x00A33BF0>
>>> i = g()
>>> i
<generator object at 0x00A37418>

Podstatné je to, že generátory podporují
stejné rozhraní (metody __iter__() a next())

>>> dir(i)
['__class__', '__delattr__', '__doc__', '__getattribute__', '__hash__', '__init__', '__iter__', '__n
ew__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__', 'close', 'gi_frame', 'gi
_running', 'next', 'send', 'throw']
>>> ii = i.__iter__()
>>> ii
<generator object at 0x00A37418>
>>> i2 = g()
>>> i2
<generator object at 0x00A37440>

Generátory lze proto využít pro implementaci
iterátoru našich vlastních datových typů.

Protokol iterátorů podporují i objekty jiných
typů, jako je například otevřený souborový objekt:

>>> f = open('a.txt')
>>> f
<open file 'a.txt', mode 'r' at 0x00A36338>
>>> dir(f)
['__class__', '__delattr__', '__doc__', '__enter__', '__exit__', '__getattribute__', '__hash__', '__
init__', '__iter__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__str__',
 'close', 'closed', 'encoding', 'fileno', 'flush', 'isatty', 'mode', 'name', 'newlines', 'next', 're
ad', 'readinto', 'readline', 'readlines', 'seek', 'softspace', 'tell', 'truncate', 'write', 'writeli
nes', 'xreadlines']

Nedá se tedy říci, že typ iterátoru je podstatný.
Podstatná je jejich funkčnost. Rozhodně nejsou
na ústupu. Spíše naopak. Prorůstají celým 
Pythonem. Představují podstatnou inovaci, která
přirozeným způsobem pomohla zobecnit například
konstrukci, které se dříve říkalo "počítaný cyklus"
(tedy cyklus for). Jejich skrytým využitím se 
zobecnil na cyklus, kterému se jinde říká
"for each" a odpovídá matematickému vyjádření
"pro všechny prvky...".

Do budoucna bude možné za určitých předpokladů
iterátory využít k paralelizaci úloh (souběžné 
zpracování iterovaných prvků více procesy nebo 
procesory). Jsou pro tento účel mnohem vhodnější,
než například počítaný cyklus, protože pokud 
říkají něco o způsobu průchodu kolekcí, pak jde
jen o dohodu -- implementační, ne nezbytný rys.

pepr


Další informace o konferenci Python