Is it a class or a function?

Share
Copied to clipboard.
Trey Hunner smiling in a t-shirt against a yellow wall
Trey Hunner
4 min. read Watch as video Python 3.10—3.14

In Python, it's not always easy to tell the difference between a class and a function... at least not from the perspective of a user of that class or a function.

Classes are callable in Python

To create a new instance of a class in Python, we call the class:

>>> from collections import Counter
>>> counts = Counter()

Calling a class returns a new instance of that class:

>>> counts
Counter()

That is, an object whose type is that class:

>>> type(counts)
<class 'collections.Counter'>

In Python, the syntax for calling a function is the same as the syntax for making a new class instance.

Both functions and classes can be called. Functions are called to evaluate the code in that function, and classes are called to make a new instance of that class.

print

Is print a class or a function?

>>> print("Class or function?")
Class or function?

Pause and take a guess.

...

What do you think? Is print a class or a function?

It turns out...

>>> print
<built-in function print>

It's a function!

That kind of makes sense. We don't get a new instance of a print object back when we call the print function. Instead, the print function does a thing for us.

Functions often do a thing. But sometimes, they return a thing.

str

What about str? Is str a class or a function?

>>> str(4)
'4'

Again, pause and take a guess.

...

It turns out that str...

>>> str
<class 'str'>

... is a class!

When we call the str function, we get back a new string object.

That is, we get an object whose type is str:

>>> type("Hello")
<class 'str'>

The "str function"?

You may have noticed that I just said: when we call the str function, we get back a new string object. But shouldn't I have said when we call the str class, we get back a new string object?

Well, both of these phrases are actually used in the Python world. I'll get to why that is later.

But first, let's take some more guesses.

list

What about list? Is list a class or a function?

>>> list(range(5))
[0, 1, 2, 3, 4]

What's your guess?

...

Turns out, list is...

>>> list
<class 'list'>

... also a class!

When we call list, we get back a new list object.

That is, we get an object whose type is list:

>>> type([1, 2, 3])
<class 'list'>

sum

What about sum? Is sum a class or a function?

>>> sum(range(5))
10

...

sum is...

>>> sum
<built-in function sum>

... a function!

When we call the sum function, the code in that function is run and it returns a number to us.

bool

What about bool? Class or function?

>>> bool("")
False

...

bool is...

>>> bool
<class 'bool'>

... a class!

enumerate

What about enumerate? Is enumerate a class or a function?

>>> colors = ["purple", "blue", "green"]
>>> for n, color in enumerate(colors):
...     print(n, color)
...
0 purple
1 blue
2 green

enumerate is...

>>> enumerate
<class 'enumerate'>

... also a class!

I pretty much always say "the enumerate function". But under the hood, it's technically implemented as a class.

type

What about type? Is type a class or a function?

>>> type(4)
<class 'int'>

Strangely, type is also a class:

>>> type
<class 'type'>

I always say the type function. It would be bizarre to say that "we call the type class" to get back the type of something.

When we need to call the type function to get an object's class, it's not our concern how type is implemented. To us, we think of it as a function because it feels like it should be a function.

We usually call "callables" functions

If an object can be looped over, it's an iterable. If an object can be called, it's a callable.

Functions are callables, and so are classes.

If you wanted to be very pedantic, you could insist on using the word "callable" every time that you refer to something that you know can be called, but you're not sure whether it's implemented as a function or a class.

But most Python programmers just use the word "function" loosely.

When I say "function", I often mean "callable". And that's okay.

Why the distinction doesn't matter

Our fuzzy use of the word "function" in Python might seem confusing. But this fuzziness is consistent with Python's embrace of duck typing.

Duck typing is about focusing on the behavior of objects instead of focusing their types.

When describing duck typing, we often say:

If it looks like a duck and quacks like a duck, it's a duck.

From a user's perspective, classes and functions look the same. We call both of them using parentheses:

>>> print("hello")  # Calling a function
hello
>>> str(4)  # Calling a class
'4'

Class or function is just an implementation detail

Whether something happens to be implemented as a class or a function is often just an implementation detail. What matters is: can you call it?

When we say "the enumerate function", we really mean "the enumerate callable".

But "callable" sounds like an overly technical word, so we often just say "function". And in Python, that's fine!

If something feels more like a function than a class, we often just call it a function.

A Python Tip Every Week

Need to fill-in gaps in your Python skills? I send weekly emails designed to do just that.