Jawaban di atas bagus, tetapi karena sebagian besar dari apa yang saya lihat, jangan terlalu menekankan perbedaan untuk orang-orang seperti saya.
Juga, orang cenderung menjadi "terlalu Pythonic" dengan meletakkan definisi seperti "X adalah objek yang memiliki __foo__()
metode" sebelumnya. Definisi seperti itu benar - mereka didasarkan pada filosofi pengetikan bebek, tetapi fokus pada metode cenderung terjadi ketika mencoba memahami konsep dalam kesederhanaannya.
Jadi saya menambahkan versi saya.
Dalam bahasa alami,
- iterasi adalah proses mengambil satu elemen pada satu waktu dalam deretan elemen.
Dengan Python,
iterable adalah objek yang, yah, iterable, yang sederhananya, berarti dapat digunakan dalam iterasi, misalnya dengan for
loop. Bagaimana? Dengan menggunakan iterator . Saya akan jelaskan di bawah.
... iterator sementara adalah objek yang mendefinisikan bagaimana sebenarnya melakukan iterasi - khususnya apa elemen berikutnya . Itu sebabnya harus ada
next()
metode.
Iterator sendiri juga dapat diubah, dengan perbedaan bahwa __iter__()
metode mereka mengembalikan objek yang sama ( self
), terlepas dari apakah itemnya telah dikonsumsi oleh panggilan sebelumnya atau tidak next()
.
Jadi apa yang dipikirkan oleh juru bahasa Python ketika ia melihat for x in obj:
pernyataan?
Lihat, satu for
lingkaran. Sepertinya pekerjaan untuk iterator ... Mari kita ambil satu. ... Ada obj
orang ini , jadi mari kita tanyakan padanya.
"Tuan obj
, apakah Anda memiliki iterator?" (... panggilan iter(obj)
, panggilan
obj.__iter__()
, yang dengan senang hati membagikan iterator baru yang mengkilap _i
.)
OK, itu mudah ... Mari kita mulai iterasi. ( x = _i.next()
... x = _i.next()
...)
Karena Mr. obj
berhasil dalam tes ini (dengan memiliki metode tertentu mengembalikan iterator yang valid), kami menghadiahinya dengan kata sifat: Anda sekarang dapat memanggilnya "Mr. iterable obj
".
Namun, dalam kasus sederhana, Anda biasanya tidak mendapat manfaat dari memiliki iterator dan iterable secara terpisah. Jadi Anda mendefinisikan hanya satu objek, yang juga merupakan iteratornya sendiri. (Python tidak benar-benar peduli yang _i
diberikan oleh obj
tidak semua yang mengkilap, tetapi hanya obj
itu sendiri.)
Inilah sebabnya mengapa dalam kebanyakan contoh yang saya lihat (dan apa yang membingungkan saya berulang kali), Anda dapat melihat:
class IterableExample(object):
def __iter__(self):
return self
def next(self):
pass
dari pada
class Iterator(object):
def next(self):
pass
class Iterable(object):
def __iter__(self):
return Iterator()
Namun, ada beberapa kasus ketika Anda dapat memanfaatkan iterator terpisah dari iterable, seperti ketika Anda ingin memiliki satu baris item, tetapi lebih banyak "kursor". Misalnya ketika Anda ingin bekerja dengan elemen "saat ini" dan "yang akan datang", Anda dapat memiliki iterator yang terpisah untuk keduanya. Atau beberapa utas menarik dari daftar besar: masing-masing dapat memiliki iterator sendiri untuk melintasi semua item. Lihat jawaban @ Raymond dan @ glglgl di atas.
Bayangkan apa yang bisa Anda lakukan:
class SmartIterableExample(object):
def create_iterator(self):
# An amazingly powerful yet simple way to create arbitrary
# iterator, utilizing object state (or not, if you are fan
# of functional), magic and nuclear waste--no kittens hurt.
pass # don't forget to add the next() method
def __iter__(self):
return self.create_iterator()
Catatan:
Saya akan ulangi lagi: iterator tidak bisa diubah . Iterator tidak dapat digunakan sebagai "sumber" di for
loop. Apa yang for
dibutuhkan terutama loop __iter__()
(yang mengembalikan sesuatu dengan next()
).
Tentu saja, for
bukan satu-satunya loop iterasi, jadi di atas berlaku untuk beberapa konstruksi lain juga ( while
...).
Iterator next()
dapat membuang StopIteration untuk menghentikan iterasi. Tidak harus, meskipun, itu dapat beralih selamanya atau menggunakan cara lain.
Dalam "proses berpikir" di atas, _i
tidak benar-benar ada. Saya telah mengarang nama itu.
Ada perubahan kecil dalam Python 3.x: next()
metode (bukan built-in) sekarang harus dipanggil__next__()
. Ya, seharusnya seperti itu selama ini.
Anda juga dapat menganggapnya seperti ini: iterable memiliki data, iterator menarik item berikutnya
Penafian: Saya bukan pengembang interpreter Python, jadi saya tidak benar-benar tahu apa yang "dipikirkan" penerjemah. Renungan di atas semata-mata menunjukkan bagaimana saya memahami topik dari penjelasan lain, percobaan dan pengalaman kehidupan nyata dari seorang pemula Python.
collections.abc.AsyncIterator
tes__aiter__
dan__anext__
metode. Ini adalah tambahan baru di 3.6.