client = pymongo.MongoClient(os.environ['CHANGE_STREAM_DB'])
change_stream = client.changestream.collection.watch()
for change in change_stream:
print(dumps(change))
print('') # for readability only
saıtrda bir lsite oluşturuluyor ve bu liste sürekli güncelleniyor, aynı şekilde for döngüsü ile itere edilirken döngü hiç bitmiyor ve eklenmeye devam ediyor, eklendikçe işlem yapmaya devam ediyor. Bu nasıl oluyor?
MongoClient.watch fonksiyonunun docstring’inde şöyle bir ifade yer alıyor,
The :class:`~pymongo.change_stream.ClusterChangeStream` iterable
blocks until the next change document is returned or an error is
raised. If the
:meth:`~pymongo.change_stream.ClusterChangeStream.next` method
encounters a network error when retrieving a batch from the server,
it will automatically attempt to recreate the cursor such that no
change events are missed. Any error encountered during the resume
attempt indicates there may be an outage and will be raised.
change_stream.ChangeStream.next fonksiyonu:
def __iter__(self):
return self
[...]
def next(self):
"""Advance the cursor.
This method blocks until the next change document is returned or an
unrecoverable error is raised. This method is used when iterating over
all changes in the cursor.
[...]
Raises :exc:`StopIteration` if this ChangeStream is closed.
"""
while self.alive:
doc = self.try_next()
if doc is not None:
return doc
raise StopIteration
__next__ = next
[...]
Anlayacağınız, next fonksiyonu her çağrıldığında try_next() fonksiyonunun döndürdüğü obje return ediliyor. Bu sayede try_next bir şeyler döndürdüğü sürece ChangeStream objesi de bir şeyler döndürebiliyor.
Generator’lari (veya yield'i) arastirmak isteyebilirsin. Yukaridaki iterable (veya Python’da her ne isim veriliyorsa) konseptini de aralarina alan birbirine cok yakin konseptlerin en anlasilani:
import time
def foo():
i = 0
while True:
time.sleep(1)
yield i
i += 1
for f in foo():
print(f)