Enumerate() function or class?

I was learning about enumerate(). While learning, when I used,

help(enumerate)

Help on class enumerate in module builtins:

class enumerate(object)
| enumerate(iterable, start=0)
|
| Return an enumerate object.
|
| iterable
| an object supporting iteration
|
| The enumerate object yields pairs containing a count (from start, which
| defaults to zero) and a value yielded by the iterable argument.
|
| enumerate is useful for obtaining an indexed list:
| (0, seq[0]), (1, seq[1]), (2, seq[2]), …
|
| Methods defined here:
|
| getattribute(self, name, /)

| Return getattr(self, name).
|
| iter(self, /)
| Implement iter(self).
|
| next(self, /)
| Implement next(self).
|
| reduce(…)
| Return state information for pickling.

Static methods defined here:
new(*args, **kwargs) from builtins.type
Create and return a new object. See help(type) for accurate signature.

Even when I gave as,

enumerate

Output was :
<class ‘enumerate’>

But, when I checked the documentation in the official website of python, www.python.org for enumerate,

Here : Built-in Functions — Python 3.9.7 documentation

It showed that enumerate() is a function which violated the information shown by help().

I couldn’t get whether enumerate() is a class or a function. Anyone please help me out of this please…

By the way, I had python 3.8.3. I even checked in python 3.6 and 3.7.10.

enumerate is definitely a class, and it returns enumerate objects.
That’s what enumerate is, according to its object type.

enumerate is also a function, according to how we use it.

In Python, the word “function” can have various meanings.

One meaning in Python is that a function is a specific type of
object, created with the def statement or the lambda keyword, which
can be called using syntax like this:

function( ... )

that returns a value or has some effect.

Another meaning is that a function can be any sort of object that
can be called using that same syntax, not just function objects. They
can include:

  • function objects created with def or lambda
  • functions that are pre-existing in the interpreter
  • builtin-function-or-method functions
  • classes or types
  • special instances that can be called like a function
  • bound methods
  • partial objects
  • and any other callable object.

If you care about how you use enumerate, then you use it as a
function. It is a function in that sense.

If you care about what kind of object enumerate is, then it is a
class.

Then obviously the documentation in the official website of python is wrong. Am I right? Even type() is a class and the Python website shows it correctly. But it shows wrong info for enumerate().

Python website has to make this change right?

To whom should we approach regarding this?

As I read it, enumerate being a class is an implementation detail. It would be OK if it was a generator (like the one in the docs), and technically you shouldn’t depend on it being a class (or returning objects of a distinct type).
In other words, isinstance(x, type) is perfectly OK, but isinstance(x, enumerate) or isinstance(x, zip) ties your code to CPython (and similar interpreters).

Not that it matters in practice, really.

I was learning about enumerate(). While learning, when I used,

help(enumerate)
Help on class enumerate in module builtins:
class enumerate(object)
[…]

Even when I gave as,

enumerate
Output was :
<class ‘enumerate’>

Therefore it is a class.

But, when I checked the documentation in the official website of python, www.python.org for enumerate,
Here : Built-in Functions — Python 3.9.7 documentation
It showed that enumerate() is a function which violated the information
shown by help().

I couldn’t get whether enumerate() is a class or a function. Anyone
please help me out of this please…

It is clearly a class, as shown when you inspected it. However, in the
past it probably was a function (I have not checked).

In some ways it doesn’t matter, as a user of enumerate. Both functions
and classes are callable. When you call a function of course you get
back some value; an object in Python since all values are objects. When
you call a class you get back an instance of the class, also an object.

In this case the main difference is how enumeration is implemented.
Currently enumerate is a class which returns an “enumerate” instance,
which happens to implement iteration. It could also be implemented as a
generator function, for example (untested):

def enumerate(something, start=0):
    for item in something:
        yield start, item
        start += 1

Cheers,
Cameron Simpson cs@cskk.id.au

Apparently there are technical reasons why built-in generators in
CPython have to be implemented as classes.

https://bugs.python.org/issue45154#msg401494

1 Like

PEP 279 enumerate() could have been implemented in Python 2.3 (source code) as a pure-Python generator function that returns an instance of types.GeneratorType, or as a builtin function that returns an instance of a hypothetical types.EnumerateType. It’s just more efficient (compared to bytecode in a generator function) and/or simpler in CPython to implement a builtin enumerate type that’s directly callable.

Ah. I was imaging it was just performance. Thanks for the reference. -
Cameron

In math, a ‘function’ is anything that produces a determined output for any input in its range. In Python, ‘function’ is the internal name of the class of objects produced by Python def statements and lambda expression. Functions defined in and other language are not ‘function’ instances.

In CPython, “builtin functions” are callables defined in C. That is what ‘builtin’ means for CPython. None of them are instances of class ‘function’. However, the Python docs define the Python language, not the CPython implementation thereof. The builtin classes whose return values are intended to be used as class instances in any implementation, such int and list, are documented as such in this chapter. The callables implemented as classes in CPython only for convenience are not documented as classes because they can be implemented otherwise in other languages.

So ‘list’ in PyPy must be a class there also, whereas ‘enumerate’ could be a generator instance.

In Python, I believe, any object that implements the call magic function can be called as if it were a function. So generate can be both a class (which is also an object), an object, and look like a function.