50 lines
1.8 KiB
Markdown
50 lines
1.8 KiB
Markdown
# iterators
|
|
|
|
> The iterator pattern allows you to perform some task on a sequence of items
|
|
> in turn. An iterator is responsible for the logic of iterating over each item
|
|
> and determining when the sequence has finished.
|
|
[Rust book](https://doc.rust-lang.org/book/ch13-02-iterators.html)
|
|
|
|
An itetarator it's usually related to some sort of lists, vectors or collection
|
|
of items, but the iterator can be anything that implements the interface. The
|
|
interaface depends on the language, but usually only needs a `next(Self) -> Item`
|
|
method that returns the next item to be acted upon.
|
|
|
|
The adventage of iterators is that you can use them with anything that accept
|
|
thems (kinda in the reusable side of programming), and modern standard
|
|
libraries implements patterns to use them like: `forEach`, `map`, `sum`, etc
|
|
|
|
Another common use case is to iterate on something indefinetly as long as it
|
|
continue to provide new items. For example you can implement a
|
|
`PollingIterator` that fetch data from a remote source until the source says
|
|
there's no more data:
|
|
|
|
```python
|
|
class EmailPoll:
|
|
"""Iterator class that pools emails from the EmailService indefinetly."""
|
|
|
|
def __init__(self, service: EmailService, wait_time: int):
|
|
super(EmailPoll, self).__init__()
|
|
self.service = service
|
|
self.wait_time = wait_time
|
|
self.current_mails = self.service.fetch_emails()
|
|
|
|
def __iter__(self):
|
|
return self
|
|
|
|
def __next__(self):
|
|
while len(self.current_mails) == 0:
|
|
self.current_mails = self.service.fetch_emails()
|
|
|
|
if len(self.current_mails) == 0:
|
|
print(f"No new emails, waiting {self.wait_time}s")
|
|
sleep(self.wait_time)
|
|
|
|
return self.current_mails.pop(0)
|
|
|
|
|
|
email_service = EmailService()
|
|
for mail in EmailPoll(email_service, 3):
|
|
print(mail)
|
|
|
|
```
|