On 5/2/2015 5:31 PM, Ian Kelly wrote:

Would it have been better if range() had been implemented as xrange()
from the beginning? Sure, that would have been great. Except for one
small detail: the iterator protocol didn't exist back then.

For loops originally used the getitem iterator protocol. xrange objects have a __getitem__ method, but not __iter__ or __next__. As Mark pointed out, they were introduced in 1993.

Getitem iterators still work. If iter(ob) is passed object ob without .__iter__, iter looks for ob.__getitem__ and if present, returns iterator(ob), where iterator is an internal protocol adapter class. Its __next__ method calls ob.__getitem__ and converts IndexError to StopIteration.

In 3.4.3:

class xrange:
    def __init__(self, start, stop, step):
        if step < 1:
            raise ValueError('incomplete xrange require positive step')
        self.val = start
        self.stop = stop
        self.step = step
    def __getitem__(self, dummy):
        val = self.val
        self.val = val + self.step
        if val < self.stop:
            return val
        else:
            raise IndexError('')

it = iter(xrange(1, 10, 3))
print(type(it))
for i in it:
    print(i)
#
<class 'iterator'>
1
4
7

--
Terry Jan Reedy

--
https://mail.python.org/mailman/listinfo/python-list

Reply via email to