PyoIterable
Bases: Checkable, Fluent, Protocol
flowchart TD
pyochain.abc._iterable.PyoIterable[PyoIterable]
pyochain.abc._mixins.Checkable[Checkable]
pyochain.abc._mixins.Fluent[Fluent]
pyochain.abc._mixins.Pipe[Pipe]
pyochain.abc._mixins.Tap[Tap]
pyochain.abc._mixins.Checkable --> pyochain.abc._iterable.PyoIterable
pyochain.abc._mixins.Fluent --> pyochain.abc._iterable.PyoIterable
pyochain.abc._mixins.Pipe --> pyochain.abc._mixins.Fluent
pyochain.abc._mixins.Tap --> pyochain.abc._mixins.Fluent
click pyochain.abc._iterable.PyoIterable href "" "pyochain.abc._iterable.PyoIterable"
click pyochain.abc._mixins.Checkable href "" "pyochain.abc._mixins.Checkable"
click pyochain.abc._mixins.Fluent href "" "pyochain.abc._mixins.Fluent"
click pyochain.abc._mixins.Pipe href "" "pyochain.abc._mixins.Pipe"
click pyochain.abc._mixins.Tap href "" "pyochain.abc._mixins.Tap"
Base ABC for all pyochain Iterables.
It's the common API surface shared by:
- eager
Collections:Seq,Vec,Set,SetMut,Dict - lazy
Iterator:Iter
It extends the standard Iterable[T] protocol, as well as Fluent and Checkable.
All concrete subclasses must implement __iter__().
Note
The difference between an Iterable and an Iterator is often misunderstood, but it's actually quite simple.
An Iterable is any object that can create an Iterator.
It's sole responsbility is to provide an __iter__ method.
This method must return an object that have a __next__ method, which is the actual Iterator.
An Iterator is an object that can produce elements one at a time, and can be exhausted.
When you do a for x in my_iterable, Python implicitly calls my_iterable.__iter__(), and then repeatedly callsnext()on the resultingIterator` to get the elements.
More concretely, a list, for example, is an Iterable.
You can't call next() on a list, because it don't know how to produce elements by itself, it's primary responsibility being to store them.
However, as soon as you call map(my_list), [x for x in my_list], (*my_list), or any other operation that needs to visit elements, an Iterator is created (implicitly or explicitly) from the list.
It's also why abc::Iterator::__iter__ returns Self by convention.
Example
Since it's very straightforward to implement, it can very easily be integrated into business logic classes to provide them with a rich set of methods for free.
from pyochain.abc import PyoIterable
from dataclasses import dataclass
@dataclass(slots=True)
class ClientRegistry(PyoIterable[str]):
clients: list[str]
def __iter__(self):
return iter(self.clients)
registry = ClientRegistry(["Alice", "Bob", "Charlie"])
assert not registry.iter().all(lambda name: name.startswith("A"))
assert registry.iter().join(", ") == "Alice, Bob, Charlie"
assert registry.iter().map(str.lower).join(", ") == "alice, bob, charlie"
x = (
registry
.ok_or("Registry is empty")
.map(lambda s: s.iter().join(", "))
.unwrap()
)
assert x == ("Alice, Bob, Charlie")
Source code in pyochain/abc/_iterable.pyi
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | |
iter()
Returns a PyoIterator object over the Iterable.
By default, this returns an Iter, but can be overriden by concrete subclasses.
This method is the pyochain equivalent of the __iter__ dunder method.
Returns:
| Type | Description |
|---|---|
PyoIterator[I]
|
PyoIterator[I]: An |
Example
from pyochain import Seq
seq = Seq(1, 2, 3)
iterator = seq.iter()
assert iterator.collect(Seq) == Seq(1, 2, 3)
# iterator is now empty
assert iterator.collect(Seq).is_empty()
assert iterator.next().is_none()
Source code in pyochain/abc/_iterable.pyi
72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 | |