@@ -657,17 +657,51 @@ Result in the stdout:
657
657
658
658
659
659
.. _PySequenceMethods : https://docs.python.org/3/c-api/typeobj.html#c.PySequenceMethods
660
+ .. _reversed() : https://docs.python.org/3/library/functions.html#reversed
661
+ .. _\_ _reversed__() : https://docs.python.org/3/reference/datamodel.html#object.__reversed__
662
+ .. _\_ _len__() : https://docs.python.org/3/reference/datamodel.html#object.__len__
663
+ .. _\_ _getitem__() : https://docs.python.org/3/reference/datamodel.html#object.__getitem__
664
+
665
+ .. index ::
666
+ single: Reverse Iterators
667
+ single: Iterators; Reverse
668
+ single: PySequenceMethods
669
+ single: __reversed__()
670
+ single: __len__()
671
+ single: __getitem__()
660
672
661
673
-----------------------------------------
662
674
Reverse Iterators
663
675
-----------------------------------------
664
676
665
- Reverse iterators are slightly unusual, the ``reversed() `` function calls the object ``__reversed__ `` method and that
666
- in turn uses ``__len__ `` and ``__getitem__ ``.
677
+ If we try and use the `reversed() `_ function on our current ``SequenceOfLong `` we will get an error:
678
+
679
+ .. code-block :: text
680
+
681
+ TypeError: 'SequenceOfLong' object is not reversible
682
+
683
+ Reverse iterators are slightly unusual, the `reversed() `_ function calls the object `__reversed__() `_ method if
684
+ available or falls back on using `__len__() `_ and `__getitem__() `_.
685
+
686
+ `reversed() `_ acts like this python code:
687
+
688
+ .. code-block :: python
689
+
690
+ def reversed (obj : object ):
691
+ if hasattr (obj, ' __reversed__' ):
692
+ yield from obj.__reversed__ ()
693
+ elif hasattr (obj, ' __len__' ) and hasattr (obj, ' __getitem__' ):
694
+ i = len (obj) - 1
695
+ while i >= 0 :
696
+ yield obj[i]
697
+ i -= 1
698
+ else :
699
+ raise TypeError (f ' { type (object )} is not reversible ' )
700
+
667
701
668
- To support this in C we need to implement these last two methods using the `PySequenceMethods `_ method table.
702
+ To support this in C we can implement ` __len__() `_ and ` __getitem__() `_ using the `PySequenceMethods `_ method table.
669
703
670
- First the implementation of `` __len__ `` in C:
704
+ First the implementation of `__len__() `_ in C:
671
705
672
706
.. code-block :: c
673
707
@@ -676,7 +710,7 @@ First the implementation of ``__len__`` in C:
676
710
return ((SequenceOfLong *)self)->size;
677
711
}
678
712
679
- Then the implementation of `` __getitem__ ``, not here that we support negative indexes and set and exception if the
713
+ Then the implementation of `__getitem__() `_, note here that we support negative indexes and set and exception if the
680
714
index is out of range:
681
715
682
716
.. code-block :: c
0 commit comments