subclassing the builtin enumerate in python

Question:

Consider the code below. I am trying to subclass the builtin enumerate so that it prints a line for every turn of the for loop. The code seems to be working, which is surprising, because I have never called super().__init__(x). So, what is happening here? Who is initializing the base class enumerate the right way? Is there some magic from the __new__ method happening here?

class myenum(enumerate):
    def __init__(self,x):
        self.x_   = x
        self.len_ = len(x)
        
    def __next__(self):
        out = super().__next__()
        print(f'Doing {out[0]} of {self.len_}')
        return out

for ictr, key in myenum(['a','b','c','d','e']):
    print('Working...')
Asked By: NNN

||

Answers:

The __init__ method is always optional. All initialization of an instance can always be done purely in the __new__ method, which is the case for the enumerate class, whose __new__ method is defined here in the enum_new_impl function, where you can see that the iterable argument is stored as the attribute en_sit of the returning object en, of the struct type enumobject:

static PyObject *
enum_new_impl(PyTypeObject *type, PyObject *iterable, PyObject *start)
{
    enumobject *en;

    ...

    en->en_sit = PyObject_GetIter(iterable);

    ...

    return (PyObject *)en;
}
Answered By: blhsing
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.