Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

subclassing the builtin enumerate in python

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...')
like image 508
Nachiket Avatar asked Jun 16 '26 15:06

Nachiket


1 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;
}
like image 145
blhsing Avatar answered Jun 18 '26 06:06

blhsing



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!