diff options
Diffstat (limited to 'Python/Dependencies/future-0.18.2/docs/custom_iterators.rst')
| -rw-r--r-- | Python/Dependencies/future-0.18.2/docs/custom_iterators.rst | 94 |
1 files changed, 0 insertions, 94 deletions
diff --git a/Python/Dependencies/future-0.18.2/docs/custom_iterators.rst b/Python/Dependencies/future-0.18.2/docs/custom_iterators.rst deleted file mode 100644 index 6ff389a..0000000 --- a/Python/Dependencies/future-0.18.2/docs/custom_iterators.rst +++ /dev/null @@ -1,94 +0,0 @@ -.. _custom-iterators: - -Custom iterators ----------------- - -If you define your own iterators, there is an incompatibility in the method name -to retrieve the next item across Py3 and Py2. On Python 3 it is ``__next__``, -whereas on Python 2 it is ``next``. - -The most elegant solution to this is to derive your custom iterator class from -``builtins.object`` and define a ``__next__`` method as you normally -would on Python 3. On Python 2, ``object`` then refers to the -``future.types.newobject`` base class, which provides a fallback ``next`` -method that calls your ``__next__``. Use it as follows:: - - from builtins import object - - class Upper(object): - def __init__(self, iterable): - self._iter = iter(iterable) - def __next__(self): # Py3-style iterator interface - return next(self._iter).upper() - def __iter__(self): - return self - - itr = Upper('hello') - assert next(itr) == 'H' - assert next(itr) == 'E' - assert list(itr) == list('LLO') - - -You can use this approach unless you are defining a custom iterator as a -subclass of a base class defined elsewhere that does not derive from -``newobject``. In that case, you can provide compatibility across -Python 2 and Python 3 using the ``next`` function from ``future.builtins``:: - - from builtins import next - - from some_module import some_base_class - - class Upper2(some_base_class): - def __init__(self, iterable): - self._iter = iter(iterable) - def __next__(self): # Py3-style iterator interface - return next(self._iter).upper() - def __iter__(self): - return self - - itr2 = Upper2('hello') - assert next(itr2) == 'H' - assert next(itr2) == 'E' - -``next()`` also works with regular Python 2 iterators with a ``.next`` method:: - - itr3 = iter(['one', 'three', 'five']) - assert 'next' in dir(itr3) - assert next(itr3) == 'one' - -This approach is feasible whenever your code calls the ``next()`` function -explicitly. If you consume the iterator implicitly in a ``for`` loop or -``list()`` call or by some other means, the ``future.builtins.next`` function -will not help; the third assertion below would fail on Python 2:: - - itr2 = Upper2('hello') - - assert next(itr2) == 'H' - assert next(itr2) == 'E' - assert list(itr2) == list('LLO') # fails because Py2 implicitly looks - # for a ``next`` method. - -Instead, you can use a decorator called ``implements_iterator`` from -``future.utils`` to allow Py3-style iterators to work identically on Py2, even -if they don't inherit from ``future.builtins.object``. Use it as follows:: - - from future.utils import implements_iterator - - Upper2 = implements_iterator(Upper2) - - print(list(Upper2('hello'))) - # prints ['H', 'E', 'L', 'L', 'O'] - -This can of course also be used with the ``@`` decorator syntax when defining -the iterator as follows:: - - @implements_iterator - class Upper2(some_base_class): - def __init__(self, iterable): - self._iter = iter(iterable) - def __next__(self): # note the Py3 interface - return next(self._iter).upper() - def __iter__(self): - return self - -On Python 3, as usual, this decorator does nothing. |
