Sonsuz Iterasyonlu Liste (Nasıl?)

Selamlar
PyMongo dokümanlarını incelerken bir şey ile karşılaştım.

Link: https://www.mongodb.com/blog/post/mongodb-change-streams-with-python

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
  1. 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?

Bu linkleri inceleyebilirsiniz.

Edit: Şöyle bir örnek bırakmak istedim,

In [1]: class IntStream(object):
   ...:     def __init__(self):
   ...:         self.start = 0
   ...:         self.alive = True
   ...:
   ...:     def __iter__(self):
   ...:         return self
   ...:
   ...:     def __next__(self):
   ...:         while self.alive:
   ...:             self.start += 1
   ...:             return self.start
   ...:
   ...:         raise StopIteration

In [2]: stream = IntStream()

In [3]: for x in stream:
   ...:     if x > 5:
   ...:         stream.alive = False
   ...:

In [4]: x
Out[4]: 6

selamlar, inceledim ama pek bir şey anlamadım açıkçası.

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.

Tamam da

list = ["a", "b", "c"]
for i in list:
    print(i)

Bu şekilde liste eleman sayısı bitince, döngünün bitmesi gerekmiyor mu? Ama bu şekilde nedense bitmiyor?

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)
1 Beğeni